Beispiel #1
0
    def solve(self, with_duals=False, tee=True, logfile=None, solver=None):
        if solver is None:
            solver_name = cfg.get('general', 'solver')
        else:
            solver_name = solver

        logging.info("Optimising using {0}.".format(solver_name))

        if with_duals:
            self.model.receive_duals()

        if self.debug:
            filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                    'reegis.lp')
            logging.info('Store lp-file in {0}.'.format(filename))
            self.model.write(filename,
                             io_options={'symbolic_solver_labels': True})

        self.model.solve(solver=solver_name,
                         solve_kwargs={
                             'tee': tee,
                             'logfile': logfile
                         })
        self.es.results['main'] = outputlib.processing.results(self.model)
        self.es.results['meta'] = outputlib.processing.meta_results(self.model)
        self.es.results['param'] = outputlib.processing.parameter_as_dict(
            self.es)
        self.es.results['scenario'] = self.scenario_info(solver_name)
        self.es.results['meta']['in_location'] = self.location
        self.es.results['meta']['file_date'] = datetime.datetime.fromtimestamp(
            os.path.getmtime(self.location))
        self.es.results['meta']['oemof_version'] = logger.get_version()
        self.results = self.es.results['main']
Beispiel #2
0
    def solve(self, with_duals=False, tee=True, logfile=None, solver=None):
        logging.info("Optimising using {0}.".format(solver))

        if with_duals:
            self.model.receive_duals()

        if self.debug:
            filename = os.path.join(helpers.extend_basic_path("lp_files"),
                                    "reegis.lp")
            logging.info("Store lp-file in {0}.".format(filename))
            self.model.write(filename,
                             io_options={"symbolic_solver_labels": True})

        self.model.solve(solver=solver,
                         solve_kwargs={
                             "tee": tee,
                             "logfile": logfile
                         })
        self.es.results["main"] = processing.results(self.model)
        self.es.results["meta"] = processing.meta_results(self.model)
        self.es.results["param"] = processing.parameter_as_dict(self.es)
        self.es.results["meta"]["scenario"] = self.scenario_info(solver)
        self.es.results["meta"]["in_location"] = self.location
        self.es.results["meta"]["file_date"] = datetime.datetime.fromtimestamp(
            os.path.getmtime(self.location))
        self.es.results["meta"]["oemof_version"] = logger.get_version()
        self.results = self.es.results["main"]
Beispiel #3
0
    def setup_class(self):
        self.objective_pattern = re.compile("^objective.*(?=s\.t\.)",
                                            re.DOTALL | re.MULTILINE)

        self.date_time_index = pd.date_range('1/1/2012', periods=3, freq='H')

        self.tmppath = helpers.extend_basic_path('tmp')
        logging.info(self.tmppath)
Beispiel #4
0
    def setup_class(cls):
        cls.objective_pattern = re.compile(r'^objective.*(?=s\.t\.)',
                                           re.DOTALL | re.MULTILINE)

        cls.date_time_index = pd.date_range('1/1/2012', periods=3, freq='H')

        cls.tmpdir = helpers.extend_basic_path('tmp')
        logging.info(cls.tmpdir)
Beispiel #5
0
    def setup_class(self):
        self.objective_pattern = re.compile("^objective.*(?=s\.t\.)",
                                            re.DOTALL|re.MULTILINE)

        self.date_time_index = pd.date_range('1/1/2012', periods=3, freq='H')

        self.tmppath = helpers.extend_basic_path('tmp')
        logging.info(self.tmppath)
Beispiel #6
0
def define_logging(inifile='logging.ini', basicpath=None, subdir='log_files'):
    r"""Initialise the logger using the logging.conf file in the local path.

    Several sentences providing an extended description. Refer to
    variables using back-ticks, e.g. `var`.

    Parameters
    ----------
    inifile : string, optional (default: logging.ini)
        Name of the configuration file to define the logger. If no ini-file
        exist a default ini-file will be downloaded from
        'http://vernetzen.uni-flensburg.de/~git/logging_default.ini' and used.
    basicpath : string, optional (default: '.oemof' in HOME)
        The basicpath for different oemof related informations. By default
        a ".oemof' folder is created in your home directory.
    subdir : string, optional (default: 'log_files')
        The name of the subfolder of the basicpath where the log-files are
        stored.

    Notes
    -----
    By default the INFO level is printed on the screen and the debug level
    in a file, but you can easily configure the ini-file.
    Every module that wants to create logging messages has to import the
    logging module. The oemof logger module has to be imported once to
    initialise it.

    Examples
    --------
    To define the default logge you have to import the python logging library
    and this function. The first logging message should be the path where the
    log file is saved to.

    >>> import logging
    >>> from oemof.tools import logger
    >>> logger.define_logging() # doctest: +SKIP
    17:56:51-INFO-Path for logging: /HOME/.oemof/log_files
    ...
    >>> logging.debug("Hallo")

    """
    url = 'http://vernetzen.uni-flensburg.de/~git/logging_default.ini'
    if basicpath is None:
        basicpath = helpers.get_basic_path()
    logpath = helpers.extend_basic_path(subdir)
    log_filename = os.path.join(basicpath, 'logging.ini')
    if not os.path.isfile(log_filename):
        helpers.download_file(log_filename, url)
    logging.config.fileConfig(os.path.join(basicpath, 'logging.ini'))
    logger = logging.getLogger('simpleExample')
    logger.debug('*********************************************************')
    logging.info('Path for logging: %s' % logpath)
    try:
        check_git_branch()
    except:
        check_version()
Beispiel #7
0
    def setUpClass(self):

        self.objective_pattern = re.compile("^objective.*(?=s\.t\.)",
                                            re.DOTALL|re.MULTILINE)

        self.time_index = pd.date_range('1/1/2012', periods=3, freq='H')

        self.sim = es.Simulation(
            timesteps=range(len(self.time_index)), solver='glpk',
            objective_options={
                'function': predefined_objectives.minimize_cost})

        self.tmppath = helpers.extend_basic_path('tmp')
        logging.info(self.tmppath)
Beispiel #8
0
##########################################################################
# Optimise the energy system and plot the results
##########################################################################

logging.info('Optimise the energy system')

# initialise the operational model
model = solph.Model(energysystem)

# This is for debugging only. It is not(!) necessary to solve the problem and
# should be set to True to save time and disc space in normal use. For
# debugging the timesteps should be set to 3, to increase the readability of
# the lp-file.
if debug:
    filename = os.path.join(
        helpers.extend_basic_path('lp_files'), r'C:\Users\Winfried\Oemof\results\lp\TI8784O.lp')
    logging.info('Store lp-file in {0}.'.format(filename))
    model.write(filename, io_options={'symbolic_solver_labels': True})

# if tee_switch is true solver messages will be displayed
logging.info('Solve the optimization problem')
model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

logging.info('Store the energy system with the results.')

# The processing module of the outputlib can be used to extract the results
# from the model transfer them into a homogeneous structured dictionary.

# add results to the energy system to make it possible to store them.
energysystem.results['main'] = outputlib.processing.results(model)
energysystem.results['meta'] = outputlib.processing.meta_results(model)
Beispiel #9
0
    inputs={bel: solph.Flow(nominal_value=10)},
    outputs={bel: solph.Flow(nominal_value=10, variable_costs=0.001)},
    capacity_loss=0.00, initial_capacity=None,
    inflow_conversion_factor=1, outflow_conversion_factor=1,)

energysystem.add(storage)    
   

logging.info('Optimise the energy system')
model = solph.Model(energysystem)


# nur für debug. kann ignoriert werden
if debug:
    filename = os.path.join(
        helpers.extend_basic_path('lp_files'), 'basic_example.lp')
    logging.info('Store lp-file in {0}.'.format(filename))
    model.write(filename, io_options={'symbolic_solver_labels': True})
    
    

logging.info('Solve the optimization problem')
model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

logging.info('Store the energy system with the results.')



# add results to the energy system to make it possible to store them.
energysystem.results['main'] = outputlib.processing.results(model)
energysystem.results['meta'] = outputlib.processing.meta_results(model)
Beispiel #10
0
def optimise_storage_size(energysystem, filename="variable_chp.csv",
                          solver='cbc', debug=True, tee_switch=True):

    # Read data file with heat and electrical demand (192 hours)
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")

    ##########################################################################
    # Create oemof.solph objects
    ##########################################################################

    logging.info('Create oemof.solph objects')

    # create natural gas bus
    bgas = solph.Bus(label="natural_gas")

    # create commodity object for gas resource
    solph.Source(label='rgas', outputs={bgas: solph.Flow(variable_costs=50)})

    # create two electricity buses and two heat buses
    bel = solph.Bus(label="electricity")
    bel2 = solph.Bus(label="electricity_2")
    bth = solph.Bus(label="heat")
    bth2 = solph.Bus(label="heat_2")

    # create excess components for the elec/heat bus to allow overproduction
    solph.Sink(label='excess_bth_2', inputs={bth2: solph.Flow()})
    solph.Sink(label='excess_therm', inputs={bth: solph.Flow()})
    solph.Sink(label='excess_bel_2', inputs={bel2: solph.Flow()})
    solph.Sink(label='excess_elec', inputs={bel: solph.Flow()})

    # create simple sink object for electrical demand for each electrical bus
    solph.Sink(label='demand_elec', inputs={bel: solph.Flow(
        actual_value=data['demand_el'], fixed=True, nominal_value=1)})
    solph.Sink(label='demand_el_2', inputs={bel2: solph.Flow(
        actual_value=data['demand_el'], fixed=True, nominal_value=1)})

    # create simple sink object for heat demand for each thermal bus
    solph.Sink(label='demand_therm', inputs={bth: solph.Flow(
        actual_value=data['demand_th'], fixed=True, nominal_value=741000)})
    solph.Sink(label='demand_th_2', inputs={bth2: solph.Flow(
        actual_value=data['demand_th'], fixed=True, nominal_value=741000)})

    # This is just a dummy transformer with a nominal input of zero
    solph.LinearTransformer(
        label='fixed_chp_gas',
        inputs={bgas: solph.Flow(nominal_value=0)},
        outputs={bel: solph.Flow(), bth: solph.Flow()},
        conversion_factors={bel: 0.3, bth: 0.5})

    # create a fixed transformer to distribute to the heat_2 and elec_2 buses
    solph.LinearTransformer(
        label='fixed_chp_gas_2',
        inputs={bgas: solph.Flow(nominal_value=10e10)},
        outputs={bel2: solph.Flow(), bth2: solph.Flow()},
        conversion_factors={bel2: 0.3, bth2: 0.5})

    # create a fixed transformer to distribute to the heat and elec buses
    solph.VariableFractionTransformer(
        label='variable_chp_gas',
        inputs={bgas: solph.Flow(nominal_value=10e10)},
        outputs={bel: solph.Flow(), bth: solph.Flow()},
        conversion_factors={bel: 0.3, bth: 0.5},
        conversion_factor_single_flow={bel: 0.5}
        )

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(energysystem)

    if debug:
        filename = os.path.join(
            helpers.extend_basic_path('lp_files'), 'variable_chp.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    om.solve(solver=solver, solve_kwargs={'tee': tee_switch})

    return energysystem
            initial_storage_level=param_value['init_capacity_storage_el'],
            inflow_conversion_factor=param_value[
                'inflow_conv_factor_storage_el'],
            outflow_conversion_factor=param_value[
                'outflow_conv_factor_storage_el']))

##########################################################################
# Optimise the energy system and plot the results
##########################################################################

logging.info('Optimise the energy system')

model = solph.Model(energysystem)

if cfg['debug']:
    filename = os.path.join(helpers.extend_basic_path('lp_files'), 'model.lp')
    logging.info('Store lp-file in {0}.'.format(filename))
    model.write(filename, io_options={'symbolic_solver_labels': True})

# if tee_switch is true solver messages will be displayed
logging.info('Solve the optimization problem')
model.solve(solver=cfg['solver'], solve_kwargs={'tee': cfg['solver_verbose']})

logging.info('Store the energy system with the results.')

energysystem.results['main'] = outputlib.processing.results(model)
energysystem.results['meta'] = outputlib.processing.meta_results(model)

energysystem.dump(dpath=abs_path + "/results/optimisation_results/dumps",
                  filename="model.oemof")
Beispiel #12
0
def test_helpers():
    ok_(os.path.isdir(os.path.join(os.path.expanduser('~'), '.oemof')))
    new_dir = helpers.extend_basic_path('test_xf67456_dir')
    ok_(os.path.isdir(new_dir))
    os.rmdir(new_dir)
    ok_(not os.path.isdir(new_dir))
def run_model_flexchp(config_path, scenario_nr):

    with open(config_path, 'r') as ymlfile:
        cfg = yaml.load(ymlfile)

    if cfg['debug']:
        number_of_time_steps = 3
    else:
        number_of_time_steps = 8760

    solver = cfg['solver']
    debug = cfg['debug']
    periods = number_of_time_steps
    solver_verbose = cfg['solver_verbose']

    abs_path = os.path.dirname(os.path.abspath(os.path.join(__file__, '..')))

    logger.define_logging(logpath=abs_path +
                          '/results/optimisation_results/log/',
                          logfile=cfg['filename_logfile'] +
                          '_scenario_{0}.log'.format(scenario_nr),
                          screen_level=logging.INFO,
                          file_level=logging.DEBUG)

    logging.info('Use parameters for scenario {0}'.format(scenario_nr))
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range(cfg['start_date'],
                                    periods=number_of_time_steps,
                                    freq=cfg['frequency'])

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    ##########################################################################
    # Read time series and parameter values from data files
    ##########################################################################

    file_path_demand_ts = abs_path + cfg['demand_time_series']
    data = pd.read_csv(file_path_demand_ts)

    file_path_param_01 = abs_path + cfg['parameters_energy_system'][scenario_nr
                                                                    - 1]
    file_path_param_02 = abs_path + cfg['parameters_all_energy_systems']
    param_df_01 = pd.read_csv(file_path_param_01, index_col=1)
    param_df_02 = pd.read_csv(file_path_param_02, index_col=1)
    param_df = pd.concat([param_df_01, param_df_02], sort=True)
    param_value = param_df['value']

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')

    bgas = solph.Bus(label="natural_gas")
    bel = solph.Bus(label="electricity")
    bth = solph.Bus(label='heat')

    energysystem.add(bgas, bel, bth)

    # Sources and sinks
    energysystem.add(
        solph.Sink(
            label='excess_bel',
            inputs={
                bel:
                solph.Flow(variable_costs=param_value['var_costs_excess_bel'])
            }))
    energysystem.add(
        solph.Sink(
            label='excess_bth',
            inputs={
                bth:
                solph.Flow(variable_costs=param_value['var_costs_excess_bth'])
            }))
    energysystem.add(
        solph.Source(
            label='shortage_bel',
            outputs={
                bel:
                solph.Flow(
                    variable_costs=param_value['var_costs_shortage_bel'])
            }))
    energysystem.add(
        solph.Source(
            label='shortage_bth',
            outputs={
                bth:
                solph.Flow(
                    variable_costs=param_value['var_costs_shortage_bth'])
            }))
    energysystem.add(
        solph.Source(label='rgas',
                     outputs={
                         bgas:
                         solph.Flow(
                             nominal_value=param_value['nom_val_gas'],
                             summed_max=param_value['sum_max_gas'],
                             variable_costs=param_value['var_costs_gas'])
                     }))
    energysystem.add(
        solph.Source(
            label='P2H',
            outputs={
                bth:
                solph.Flow(actual_value=data['neg_residual_el'],
                           nominal_value=param_value['nom_val_neg_residual'] *
                           param_value['conversion_factor_p2h'],
                           fixed=True)
            }))
    energysystem.add(
        solph.Sink(label='demand_el',
                   inputs={
                       bel:
                       solph.Flow(
                           actual_value=data['demand_el'],
                           nominal_value=param_value['nom_val_demand_el'],
                           fixed=True)
                   }))
    energysystem.add(
        solph.Sink(label='demand_th',
                   inputs={
                       bth:
                       solph.Flow(
                           actual_value=data['demand_th'],
                           nominal_value=param_value['nom_val_demand_th'],
                           fixed=True)
                   }))

    energysystem.add(
        solph.components.GenericCHP(
            label='CHP_01',
            fuel_input={
                bgas:
                solph.Flow(H_L_FG_share_max=[
                    param_value['H_L_FG_share_max'] for p in range(0, periods)
                ])
            },
            electrical_output={
                bel:
                solph.Flow(P_max_woDH=[
                    param_value['P_max_woDH'] for p in range(0, periods)
                ],
                           P_min_woDH=[
                               param_value['P_min_woDH']
                               for p in range(0, periods)
                           ],
                           Eta_el_max_woDH=[
                               param_value['Eta_el_max_woDH']
                               for p in range(0, periods)
                           ],
                           Eta_el_min_woDH=[
                               param_value['Eta_el_min_woDH']
                               for p in range(0, periods)
                           ])
            },
            heat_output={
                bth:
                solph.Flow(Q_CW_min=[
                    param_value['Q_CW_min_chp'] for p in range(0, periods)
                ])
            },
            Beta=[param_value['Beta_chp'] for p in range(0, periods)],
            back_pressure=False))

    energysystem.add(
        solph.Transformer(
            label='boiler',
            inputs={bgas: solph.Flow()},
            outputs={
                bth:
                solph.Flow(nominal_value=param_value['nom_val_out_boiler'],
                           variable_costs=param_value['var_costs_boiler'])
            },
            conversion_factors={bth: param_value['conversion_factor_boiler']}))

    if param_value['nom_capacity_storage_th'] > 0:
        storage_th = solph.components.GenericStorage(
            nominal_capacity=param_value['nom_capacity_storage_th'],
            label='storage_th',
            inputs={
                bth:
                solph.Flow(
                    nominal_value=param_value['nom_val_input_bth_storage_th'],
                    variable_costs=param_value[
                        'var_costs_input_bth_storage_th'])
            },
            outputs={
                bth:
                solph.Flow(
                    nominal_value=param_value['nom_val_output_bth_storage_th'],
                    variable_costs=param_value[
                        'var_costs_output_bth_storage_th'])
            },
            capacity_loss=param_value['capacity_loss_storage_th'],
            initial_capacity=param_value['init_capacity_storage_th'],
            inflow_conversion_factor=param_value[
                'inflow_conv_factor_storage_th'],
            outflow_conversion_factor=param_value[
                'outflow_conv_factor_storage_th'])
        energysystem.add(storage_th)

    if param_value['nom_capacity_storage_el'] > 0:
        storage_el = solph.components.GenericStorage(
            nominal_capacity=param_value['nom_capacity_storage_el'],
            label='storage_el',
            inputs={
                bel:
                solph.Flow(
                    nominal_value=param_value['nom_val_input_bel_storage_el'],
                    variable_costs=param_value[
                        'var_costs_input_bel_storage_el'])
            },
            outputs={
                bel:
                solph.Flow(
                    nominal_value=param_value['nom_val_output_bel_storage_el'],
                    variable_costs=param_value[
                        'var_costs_output_bel_storage_el'])
            },
            capacity_loss=param_value['capacity_loss_storage_el'],
            initial_capacity=param_value['init_capacity_storage_el'],
            inflow_conversion_factor=param_value[
                'inflow_conv_factor_storage_el'],
            outflow_conversion_factor=param_value[
                'outflow_conv_factor_storage_el'])
        energysystem.add(storage_el)

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    model = solph.Model(energysystem)

    if debug:
        lpfile_name = 'flexCHP_scenario_{0}.lp'.format(scenario_nr)
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                lpfile_name)
        logging.info('Store lp-file in {0}.'.format(filename))
        model.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

    logging.info('Store the energy system with the results.')

    energysystem.results['main'] = outputlib.processing.results(model)
    energysystem.results['meta'] = outputlib.processing.meta_results(model)

    energysystem.dump(dpath=abs_path + "/results/optimisation_results/dumps",
                      filename=cfg['filename_dumb'] +
                      '_scenario_{0}.oemof'.format(scenario_nr))
Beispiel #14
0
def define_logging(inifile='logging.ini',
                   basicpath=None,
                   subdir='log_files',
                   log_version=True):
    r"""Initialise the logger using the logging.conf file in the local path.

    Several sentences providing an extended description. Refer to
    variables using back-ticks, e.g. `var`.

    Parameters
    ----------
    inifile : string, optional (default: logging.ini)
        Name of the configuration file to define the logger. If no ini-file
         exist a default ini-file will be copied from 'default_files' and
         used.
    basicpath : string, optional (default: '.oemof' in HOME)
        The basicpath for different oemof related information. By default
        a ".oemof' folder is created in your home directory.
    subdir : string, optional (default: 'log_files')
        The name of the subfolder of the basicpath where the log-files are
        stored.
    log_version : boolean
        If True the actual version or commit is logged while initialising the
        logger.

    Notes
    -----
    By default the INFO level is printed on the screen and the debug level
    in a file, but you can easily configure the ini-file.
    Every module that wants to create logging messages has to import the
    logging module. The oemof logger module has to be imported once to
    initialise it.

    Examples
    --------
    To define the default logger you have to import the python logging
     library and this function. The first logging message should be the
     path where the log file is saved to.

    >>> import logging
    >>> from oemof.tools import logger
    >>> logger.define_logging() # doctest: +SKIP
    17:56:51-INFO-Path for logging: /HOME/.oemof/log_files
    ...
    >>> logging.debug("Hallo")

    """
    if basicpath is None:
        basicpath = helpers.get_basic_path()
    logpath = helpers.extend_basic_path(subdir)
    log_filename = os.path.join(basicpath, inifile)
    default_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                'default_files', 'logging_default.ini')
    if not os.path.isfile(log_filename):
        shutil.copyfile(default_file, log_filename)
    logging.config.fileConfig(os.path.join(basicpath, inifile))
    logger = logging.getLogger('simpleExample')
    logger.debug('*********************************************************')
    logging.info('Path for logging: %s' % logpath)
    if log_version:
        try:
            check_git_branch()
        except FileNotFoundError:
            check_version()
Beispiel #15
0
def main():

    # ****************************************************************************
    # ********** PART 1 - Define and optimise the energy system ******************
    # ****************************************************************************

    ###############################################################################
    # imports
    ###############################################################################

    # Default logger of oemof
    from oemof.tools import logger
    from oemof.tools import helpers

    import oemof.solph as solph
    import oemof.outputlib as outputlib

    import logging
    import os
    import pandas as pd
    import pprint as pp

    try:
        import matplotlib.pyplot as plt
    except ImportError:
        plt = None

    solver = 'cbc'  # 'glpk', 'gurobi',....
    debug = False  # Set number_of_timesteps to 3 to get a readable lp-file.
    number_of_time_steps = 24 * 7 * 8
    solver_verbose = False  # show/hide solver output

    # initiate the logger (see the API docs for more information)
    logger.define_logging(logfile='oemof_example.log',
                          screen_level=logging.INFO,
                          file_level=logging.DEBUG)

    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2012',
                                    periods=number_of_time_steps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    # Read data file
    filename = os.path.join(os.path.dirname(__file__), 'basic_example.csv')
    data = pd.read_csv(filename)

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')

    # The bus objects were assigned to variables which makes it easier to connect
    # components to these buses (see below).

    # create natural gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # adding the buses to the energy system
    energysystem.add(bgas, bel)

    # create excess component for the electricity bus to allow overproduction
    energysystem.add(solph.Sink(label='excess_bel', inputs={bel:
                                                            solph.Flow()}))

    # create source object representing the natural gas commodity (annual limit)
    energysystem.add(
        solph.Source(
            label='rgas',
            outputs={bgas: solph.Flow(nominal_value=29825293, summed_max=1)}))

    # create fixed source object representing wind power plants
    energysystem.add(
        solph.Source(label='wind',
                     outputs={
                         bel:
                         solph.Flow(actual_value=data['wind'],
                                    nominal_value=1000000,
                                    fixed=True)
                     }))

    # create fixed source object representing pv power plants
    energysystem.add(
        solph.Source(label='pv',
                     outputs={
                         bel:
                         solph.Flow(actual_value=data['pv'],
                                    nominal_value=582000,
                                    fixed=True)
                     }))

    # create simple sink object representing the electrical demand
    energysystem.add(
        solph.Sink(label='demand',
                   inputs={
                       bel:
                       solph.Flow(actual_value=data['demand_el'],
                                  fixed=True,
                                  nominal_value=1)
                   }))

    # create simple transformer object representing a gas power plant
    energysystem.add(
        solph.Transformer(
            label="pp_gas",
            inputs={bgas: solph.Flow()},
            outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)},
            conversion_factors={bel: 0.58}))

    # create storage object representing a battery
    storage = solph.components.GenericStorage(
        nominal_capacity=10077997,
        label='storage',
        inputs={bel: solph.Flow()},
        outputs={bel: solph.Flow(variable_costs=0.001)},
        capacity_loss=0.00,
        initial_capacity=None,
        nominal_input_capacity_ratio=1 / 6,
        nominal_output_capacity_ratio=1 / 6,
        inflow_conversion_factor=1,
        outflow_conversion_factor=0.8,
    )

    energysystem.add(storage)

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    # initialise the operational model
    model = solph.Model(energysystem)

    # This is for debugging only. It is not(!) necessary to solve the problem and
    # should be set to False to save time and disc space in normal use. For
    # debugging the timesteps should be set to 3, to increase the readability of
    # the lp-file.
    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'storage_invest.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        model.write(filename, io_options={'symbolic_solver_labels': True})

    # if tee_switch is true solver messages will be displayed
    logging.info('Solve the optimization problem')
    model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

    logging.info('Store the energy system with the results.')

    # The processing module of the outputlib can be used to extract the results
    # from the model transfer them into a homogeneous structured dictionary.

    # add results to the energy system to make it possible to store them.
    energysystem.results['main'] = outputlib.processing.results(model)
    energysystem.results['meta'] = outputlib.processing.meta_results(model)

    # The default path is the '.oemof' folder in your $HOME directory.
    # The default filename is 'es_dump.oemof'.
    # You can omit the attributes (as None is the default value) for testing cases.
    # You should use unique names/folders for valuable results to avoid
    # overwriting.

    # store energy system with results
    energysystem.dump(dpath=None, filename=None)

    # ****************************************************************************
    # ********** PART 2 - Processing the results *********************************
    # ****************************************************************************

    logging.info('**** The script can be divided into two parts here.')
    logging.info('Restore the energy system and the results.')
    energysystem = solph.EnergySystem()
    energysystem.restore(dpath=None, filename=None)

    # define an alias for shorter calls below (optional)
    results = energysystem.results['main']
    storage = energysystem.groups['storage']

    # print a time slice of the state of charge
    print('')
    print('********* State of Charge (slice) *********')
    print(results[(
        storage,
        None)]['sequences']['2012-02-25 08:00:00':'2012-02-26 15:00:00'])
    print('')

    # get all variables of a specific component/bus
    custom_storage = outputlib.views.node(results, 'storage')
    electricity_bus = outputlib.views.node(results, 'electricity')

    # plot the time series (sequences) of a specific component/bus
    if plt is not None:
        custom_storage['sequences'].plot(kind='line', drawstyle='steps-post')
        plt.show()
        electricity_bus['sequences'].plot(kind='line', drawstyle='steps-post')
        plt.show()

    # print the solver results
    print('********* Meta results *********')
    pp.pprint(energysystem.results['meta'])
    print('')

    # print the sums of the flows around the electricity bus
    print('********* Main results *********')
    print(electricity_bus['sequences'].sum(axis=0))
Beispiel #16
0
def optimise_storage_size(energysystem,
                          filename="variable_chp.csv",
                          solver='cbc',
                          debug=True,
                          tee_switch=True):

    # Read data file with heat and electrical demand (192 hours)
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")

    ##########################################################################
    # Create oemof.solph objects
    ##########################################################################

    logging.info('Create oemof.solph objects')

    # create natural gas bus
    bgas = solph.Bus(label="natural_gas")

    # create commodity object for gas resource
    solph.Source(label='rgas', outputs={bgas: solph.Flow(variable_costs=50)})

    # create two electricity buses and two heat buses
    bel = solph.Bus(label="electricity")
    bel2 = solph.Bus(label="electricity_2")
    bth = solph.Bus(label="heat")
    bth2 = solph.Bus(label="heat_2")

    # create excess components for the elec/heat bus to allow overproduction
    solph.Sink(label='excess_bth_2', inputs={bth2: solph.Flow()})
    solph.Sink(label='excess_therm', inputs={bth: solph.Flow()})
    solph.Sink(label='excess_bel_2', inputs={bel2: solph.Flow()})
    solph.Sink(label='excess_elec', inputs={bel: solph.Flow()})

    # create simple sink object for electrical demand for each electrical bus
    solph.Sink(label='demand_elec',
               inputs={
                   bel:
                   solph.Flow(actual_value=data['demand_el'],
                              fixed=True,
                              nominal_value=1)
               })
    solph.Sink(label='demand_el_2',
               inputs={
                   bel2:
                   solph.Flow(actual_value=data['demand_el'],
                              fixed=True,
                              nominal_value=1)
               })

    # create simple sink object for heat demand for each thermal bus
    solph.Sink(label='demand_therm',
               inputs={
                   bth:
                   solph.Flow(actual_value=data['demand_th'],
                              fixed=True,
                              nominal_value=741000)
               })
    solph.Sink(label='demand_th_2',
               inputs={
                   bth2:
                   solph.Flow(actual_value=data['demand_th'],
                              fixed=True,
                              nominal_value=741000)
               })

    # This is just a dummy transformer with a nominal input of zero
    solph.LinearTransformer(label='fixed_chp_gas',
                            inputs={bgas: solph.Flow(nominal_value=0)},
                            outputs={
                                bel: solph.Flow(),
                                bth: solph.Flow()
                            },
                            conversion_factors={
                                bel: 0.3,
                                bth: 0.5
                            })

    # create a fixed transformer to distribute to the heat_2 and elec_2 buses
    solph.LinearTransformer(label='fixed_chp_gas_2',
                            inputs={bgas: solph.Flow(nominal_value=10e10)},
                            outputs={
                                bel2: solph.Flow(),
                                bth2: solph.Flow()
                            },
                            conversion_factors={
                                bel2: 0.3,
                                bth2: 0.5
                            })

    # create a fixed transformer to distribute to the heat and elec buses
    solph.VariableFractionTransformer(
        label='variable_chp_gas',
        inputs={bgas: solph.Flow(nominal_value=10e10)},
        outputs={
            bel: solph.Flow(),
            bth: solph.Flow()
        },
        conversion_factors={
            bel: 0.3,
            bth: 0.5
        },
        conversion_factor_single_flow={bel: 0.5})

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(energysystem)

    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'variable_chp.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    om.solve(solver=solver, solve_kwargs={'tee': tee_switch})

    return energysystem
Beispiel #17
0
def define_logging(inifile='logging.ini', basicpath=None,
                   subdir='log_files', log_version=True):
    r"""Initialise the logger using the logging.conf file in the local path.

    Several sentences providing an extended description. Refer to
    variables using back-ticks, e.g. `var`.

    Parameters
    ----------
    inifile : string, optional (default: logging.ini)
        Name of the configuration file to define the logger. If no ini-file
         exist a default ini-file will be copied from 'default_files' and
         used.
    basicpath : string, optional (default: '.oemof' in HOME)
        The basicpath for different oemof related information. By default
        a ".oemof' folder is created in your home directory.
    subdir : string, optional (default: 'log_files')
        The name of the subfolder of the basicpath where the log-files are
        stored.
    log_version : boolean
        If True the actual version or commit is logged while initialising the
        logger.

    Returns
    -------
    str : Place where the log file is stored.

    Notes
    -----
    By default the INFO level is printed on the screen and the debug level
    in a file, but you can easily configure the ini-file.
    Every module that wants to create logging messages has to import the
    logging module. The oemof logger module has to be imported once to
    initialise it.

    Examples
    --------
    To define the default logger you have to import the python logging
     library and this function. The first logging message should be the
     path where the log file is saved to.

    >>> import logging
    >>> from oemof.tools import logger
    >>> logger.define_logging() # doctest: +SKIP
    17:56:51-INFO-Path for logging: /HOME/.oemof/log_files
    ...
    >>> logging.debug("Hallo")

    """
    if basicpath is None:
        basicpath = helpers.get_basic_path()
    logpath = helpers.extend_basic_path(subdir)
    log_filename = os.path.join(basicpath, inifile)
    default_file = os.path.join(os.path.dirname(
        os.path.realpath(__file__)), 'default_files', 'logging_default.ini')
    if not os.path.isfile(log_filename):
        shutil.copyfile(default_file, log_filename)
    logging.config.fileConfig(os.path.join(basicpath, inifile))
    try:
        returnpath = logging.getLoggerClass().root.handlers[1].baseFilename
    except AttributeError:
        returnpath = None
    logger = logging.getLogger('simpleExample')
    logger.debug('*********************************************************')
    logging.info('Path for logging: %s' % logpath)
    if log_version:
        try:
            check_git_branch()
        except FileNotFoundError:
            check_version()
    return returnpath
def run_model(config_path, team_number):

    with open(config_path, 'r') as ymlfile:
        cfg = yaml.load(ymlfile, Loader=yaml.CLoader)

    if cfg['debug']:
        number_of_time_steps = 3
    else:
        number_of_time_steps = 8760

    solver = cfg['solver']
    debug = cfg['debug']
    periods = number_of_time_steps
    solver_verbose = cfg['solver_verbose']  # show/hide solver output

    # initiate the logger (see the API docs for more information)
    logger.define_logging(logfile='model_team_{0}.log'.format(team_number + 1),
                          screen_level=logging.INFO,
                          file_level=logging.DEBUG)

    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2030',
                                    periods=number_of_time_steps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    ##########################################################################
    # Read time series and parameter values from data files
    ##########################################################################

    abs_path = os.path.dirname(os.path.abspath(os.path.join(__file__, '..')))

    file_path_ts = abs_path + '/data/' + cfg['time_series_file_name']
    data = pd.read_csv(file_path_ts)

    # file_path_weather_ts = abs_path + '/data_preprocessed/' + cfg[
    #     'weather_time_series']
    # weather_data = pd.read_csv(file_path_weather_ts)

    file_name_param_01 = cfg['design_parameters_file_name'][team_number]
    file_name_param_02 = cfg['parameters_file_name']
    file_path_param_01 = (abs_path + '/data/' + file_name_param_01)
    file_path_param_02 = (abs_path + '/data/' + file_name_param_02)
    param_df_01 = pd.read_csv(file_path_param_01, index_col=1)
    param_df_02 = pd.read_csv(file_path_param_02, index_col=1)
    param_df = pd.concat([param_df_01, param_df_02], sort=True)
    param_value = param_df['value']

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')

    bgas = solph.Bus(label="natural_gas")
    bel = solph.Bus(label="electricity")
    bth = solph.Bus(label='heat')

    energysystem.add(bgas, bel, bth)

    # Sources and sinks
    energysystem.add(
        solph.Sink(
            label='excess_bel',
            inputs={
                bel:
                solph.Flow(variable_costs=param_value['var_costs_excess_bel'])
            }))
    energysystem.add(
        solph.Sink(
            label='excess_bth',
            inputs={
                bth:
                solph.Flow(variable_costs=param_value['var_costs_excess_bth'])
            }))
    energysystem.add(
        solph.Source(
            label='shortage_bel',
            outputs={
                bel:
                solph.Flow(
                    variable_costs=param_value['var_costs_shortage_bel'])
            }))
    energysystem.add(
        solph.Source(
            label='shortage_bth',
            outputs={
                bth:
                solph.Flow(
                    variable_costs=param_value['var_costs_shortage_bth'])
            }))
    energysystem.add(
        solph.Source(label='rgas',
                     outputs={
                         bgas:
                         solph.Flow(
                             nominal_value=param_value['nom_val_gas'],
                             summed_max=param_value['sum_max_gas'],
                             variable_costs=param_value['var_costs_gas'])
                     }))

    if param_value['number_of_windturbines'] > 0:
        energysystem.add(
            solph.Source(
                label='wind_turbine',
                outputs={
                    bel:
                    solph.Flow(
                        actual_value=(data['Wind_power [kW/unit]'] *
                                      param_value['number_of_windturbines'] *
                                      0.001),  # [MWh]
                        nominal_value=1,
                        fixed=True)
                }))

    energysystem.add(
        solph.Sink(
            label='demand_el',
            inputs={
                bel:
                solph.Flow(
                    actual_value=data['Demand_el [MWh]'],  # [MWh]
                    nominal_value=1,
                    fixed=True)
            }))

    energysystem.add(
        solph.Sink(
            label='demand_th',
            inputs={
                bth:
                solph.Flow(
                    actual_value=data['Demand_th [MWh]'],  # [MWh]
                    nominal_value=1,
                    fixed=True)
            }))

    # Open-field photovoltaic power plant
    if param_value['number_of_PV_pp'] > 0:
        energysystem.add(
            solph.Source(
                label='PV_pp',
                outputs={
                    bel:
                    solph.Flow(
                        actual_value=(data['Sol_irradiation [Wh/sqm]'] *
                                      0.000001 *
                                      param_value['eta_PV']),  # [MWh/m²]
                        nominal_value=param_value['PV_pp_surface_area'] *
                        10000,  # [m²]
                        fixed=True)
                }))

    # Rooftop photovoltaic
    if param_value['area_PV'] > 0:
        energysystem.add(
            solph.Source(
                label='PV',
                outputs={
                    bel:
                    solph.Flow(
                        actual_value=(data['Sol_irradiation [Wh/sqm]'] *
                                      0.000001 *
                                      param_value['eta_PV']),  # [MWh/m²]
                        nominal_value=param_value['area_PV'] * 10000,  # [m²]
                        fixed=True)
                }))

    # Rooftop solar thermal
    if param_value['area_solar_th'] > 0:
        energysystem.add(
            solph.Source(
                label='solar_thermal',
                outputs={
                    bth:
                    solph.Flow(
                        actual_value=(data['Sol_irradiation [Wh/sqm]'] *
                                      0.000001 *
                                      param_value['eta_solar_th']),  # [MWh/m²]
                        nominal_value=param_value['area_solar_th'] *
                        10000,  # [m²]
                        fixed=True)
                }))

    if param_value['number_of_chps'] > 0:
        energysystem.add(
            solph.Transformer(
                label='chp',
                inputs={bgas: solph.Flow()},
                outputs={
                    bth:
                    solph.Flow(nominal_value=param_value['number_of_chps'] *
                               0.5),  # [MW]
                    bel:
                    solph.Flow()
                },
                conversion_factors={
                    bth: param_value['conversion_factor_bth_chp'],
                    bel: param_value['conversion_factor_bel_chp']
                }))

    if param_value['number_of_heat_pumps'] > 0:
        energysystem.add(
            solph.Transformer(
                label='heat_pump',
                inputs={bel: solph.Flow()},
                outputs={
                    bth:
                    solph.Flow(
                        nominal_value=(param_value['number_of_heat_pumps'] *
                                       param_value['COP_heat_pump']))
                },  # [MW]
                conversion_factors={bth: param_value['COP_heat_pump']}))

    if param_value['number_of_boilers'] > 0:
        energysystem.add(
            solph.Transformer(
                label='boiler',
                inputs={bgas: solph.Flow()},
                outputs={
                    bth:
                    solph.Flow(nominal_value=param_value['number_of_boilers'] *
                               3)
                },  # [MW]
                conversion_factors={
                    bth: param_value['conversion_factor_boiler']
                }))

    if param_value['capacity_thermal_storage'] > 0:
        storage_th = solph.components.GenericStorage(
            nominal_storage_capacity=(param_value['capacity_thermal_storage'] *
                                      param_value['daily_demand_th']),
            label='storage_th',
            inputs={
                bth:
                solph.Flow(
                    nominal_value=(param_value['capacity_thermal_storage'] *
                                   param_value['daily_demand_th'] /
                                   param_value['charge_time_storage_th']))
            },
            outputs={
                bth:
                solph.Flow(
                    nominal_value=(param_value['capacity_thermal_storage'] *
                                   param_value['daily_demand_th'] /
                                   param_value['charge_time_storage_th']))
            },
            loss_rate=param_value['capacity_loss_storage_th'],
            initial_storage_level=param_value['init_capacity_storage_th'],
            inflow_conversion_factor=param_value[
                'inflow_conv_factor_storage_th'],
            outflow_conversion_factor=param_value[
                'outflow_conv_factor_storage_th'])
        energysystem.add(storage_th)

    if param_value['capacity_electr_storage'] > 0:
        storage_el = solph.components.GenericStorage(
            nominal_storage_capacity=(param_value['capacity_electr_storage'] *
                                      param_value['daily_demand_el']),
            label='storage_el',
            inputs={
                bel:
                solph.Flow(
                    nominal_value=(param_value['capacity_electr_storage'] *
                                   param_value['daily_demand_el'] /
                                   param_value['charge_time_storage_el']))
            },
            outputs={
                bel:
                solph.Flow(
                    nominal_value=(param_value['capacity_electr_storage'] *
                                   param_value['daily_demand_el'] /
                                   param_value['charge_time_storage_el']))
            },
            loss_rate=param_value['capacity_loss_storage_el'],
            initial_storage_level=param_value['init_capacity_storage_el'],
            inflow_conversion_factor=param_value[
                'inflow_conv_factor_storage_el'],
            outflow_conversion_factor=param_value[
                'outflow_conv_factor_storage_el'])
        energysystem.add(storage_el)

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    model = solph.Model(energysystem)

    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'model_team_{0}.lp'.format(team_number + 1))
        logging.info('Store lp-file in {0}.'.format(filename))
        model.write(filename, io_options={'symbolic_solver_labels': True})

    # if tee_switch is true solver messages will be displayed
    logging.info(
        'Solve the optimization problem of team {0}'.format(team_number + 1))
    model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

    logging.info('Store the energy system with the results.')

    energysystem.results['main'] = outputlib.processing.results(model)
    energysystem.results['meta'] = outputlib.processing.meta_results(model)

    energysystem.dump(dpath=abs_path + "/results/optimisation_results/dumps",
                      filename="model_team_{0}.oemof".format(team_number + 1))
Beispiel #19
0
def optimise_storage_size(filename="storage_investment.csv", solver='cbc',
                          debug=True, number_timesteps=8760, tee_switch=True):
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2012', periods=number_timesteps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    # Read data file
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')
    # create natural gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # create excess component for the electricity bus to allow overproduction
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})

    # create source object representing the natural gas commodity (annual limit)
    solph.Source(label='rgas', outputs={bgas: solph.Flow(
        nominal_value=194397000 * number_timesteps / 8760, summed_max=1)})

    # create fixed source object representing wind power plants
    solph.Source(label='wind', outputs={bel: solph.Flow(
        actual_value=data['wind'], nominal_value=1000000, fixed=True,
        fixed_costs=20)})

    # create fixed source object representing pv power plants
    solph.Source(label='pv', outputs={bel: solph.Flow(
        actual_value=data['pv'], nominal_value=582000, fixed=True,
        fixed_costs=15)})

    # create simple sink object representing the electrical demand
    solph.Sink(label='demand', inputs={bel: solph.Flow(
        actual_value=data['demand_el'], fixed=True, nominal_value=1)})

    # create simple transformer object representing a gas power plant
    solph.LinearTransformer(
        label="pp_gas",
        inputs={bgas: solph.Flow()},
        outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)},
        conversion_factors={bel: 0.58})

    # If the period is one year the equivalent periodical costs (epc) of an
    # investment are equal to the annuity. Use oemof's economic tools.
    epc = economics.annuity(capex=1000, n=20, wacc=0.05)

    # create storage object representing a battery
    solph.Storage(
        label='storage',
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.Flow(variable_costs=10e10)},
        capacity_loss=0.00, initial_capacity=0,
        nominal_input_capacity_ratio=1/6,
        nominal_output_capacity_ratio=1/6,
        inflow_conversion_factor=1, outflow_conversion_factor=0.8,
        fixed_costs=35,
        investment=solph.Investment(ep_costs=epc),
    )

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    # initialise the operational model
    om = solph.OperationalModel(energysystem)

    # if debug is true an lp-file will be written
    if debug:
        filename = os.path.join(
            helpers.extend_basic_path('lp_files'), 'storage_invest.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    # if tee_switch is true solver messages will be displayed
    logging.info('Solve the optimization problem')
    om.solve(solver=solver, solve_kwargs={'tee': tee_switch})

    return energysystem
def run_model_flexchp(config_path, variation_nr):

    with open(config_path, 'r') as ymlfile:
        cfg = yaml.load(ymlfile)

    if cfg['debug']:
        number_of_time_steps = 3
    else:
        number_of_time_steps = 8760

    solver = cfg['solver']
    debug = cfg['debug']
    solver_verbose = cfg['solver_verbose']  # show/hide solver output

    abs_path = os.path.dirname(os.path.abspath(os.path.join(__file__, '..')))

    # initiate the logger (see the API docs for more information)
    logger.define_logging(logpath=(abs_path
                                   + '/results/optimisation_results/log/'),
                          logfile=(cfg['filename_logfile']+'_scenario_{0}.log'.
                                   format(variation_nr)),
                          screen_level=logging.INFO,
                          file_level=logging.DEBUG)

    logging.info('Use parameters for scenario {0}'.format(variation_nr))
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range(cfg['start_date'],
                                    periods=number_of_time_steps,
                                    freq=cfg['frequency'])

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    ##########################################################################
    # Read time series and parameter values from data files
    ##########################################################################

    file_path_demand_ts = abs_path + cfg['demand_time_series']
    data = pd.read_csv(file_path_demand_ts)

    file_path_param_01 = abs_path + cfg['parameters_energy_system']
    file_path_param_02 = abs_path + cfg['parameter_variation'][variation_nr]
    param_df_01 = pd.read_csv(file_path_param_01, index_col=1)
    param_df_02 = pd.read_csv(file_path_param_02, index_col=1)
    param_df = pd.concat([param_df_01, param_df_02], sort=True)
    param_value = param_df['value']

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')

    bgas = solph.Bus(label="natural_gas")
    bel = solph.Bus(label="electricity")
    bel_residual = solph.Bus(label="residual")
    bth = solph.Bus(label='heat')

    energysystem.add(bgas, bel, bel_residual, bth)

    # Sources and sinks
    energysystem.add(solph.Sink(
        label='excess_bel',
        inputs={bel: solph.Flow(
            variable_costs=param_value['var_costs_excess_bel'])}))

    energysystem.add(solph.Sink(
        label='excess_bth',
        inputs={bth: solph.Flow(
            variable_costs=param_value['var_costs_excess_bth'])}))

    energysystem.add(solph.Source(
        label='shortage_bel',
        outputs={bel: solph.Flow(
            variable_costs=param_value['var_costs_shortage_bel'])}))

    energysystem.add(solph.Source(
        label='shortage_bth',
        outputs={bth: solph.Flow(
            variable_costs=param_value['var_costs_shortage_bth'])}))

    energysystem.add(solph.Source(
         label='rgas',
         outputs={bgas: solph.Flow(
             nominal_value=param_value['nom_val_gas'],
             summed_max=param_value['sum_max_gas'],
             variable_costs=(param_value['var_costs_gas']
                             * param_value['gas_price_variation']))}))

    energysystem.add(solph.Source(
        label='residual_el',
        outputs={bel_residual: solph.Flow(
            actual_value=data['neg_residual_el'],
            nominal_value=param_value['nom_val_neg_residual'],
            fixed=True)}))

    if cfg['price_el_quadratic'] == True:
        energysystem.add(solph.Sink(
            label='demand_el',
            inputs={bel: solph.Flow(
                variable_costs=(param_value['el_price']
                                * param_value['price_factor_sqr']
                                * param_value['el_price_variation']
                                * data['demand_el']**2),
                nominal_value=8000)}))

    if cfg['price_el_quadratic'] == False:
        energysystem.add(solph.Sink(
            label='demand_el',
            inputs={bel: solph.Flow(
                variable_costs=(param_value['el_price']
                                * param_value['el_price_variation']
                                * data['demand_el']),
                nominal_value=8000)}))

    energysystem.add(solph.Sink(
        label='demand_th',
        inputs={bth: solph.Flow(
            actual_value=data['demand_th'],
            nominal_value=param_value['nom_val_demand_th'],
            fixed=True,
            variable_costs=(- param_value['var_costs_gas']
                            / param_value['conversion_factor_boiler']))}))

    # Auxiliary component to prevent CHP electricity being used in P2H (not
    # representing a physical component!)
    energysystem.add(solph.Transformer(
        label='oneway',
        inputs={bel_residual: solph.Flow(
            nominal_value=param_value['nom_val_neg_residual'])},
        outputs={bel: solph.Flow()},
        conversion_factors={bel: 1}))

    # Combined Heat and Power Plant (CHP)
    # Calculate annuity per installed unit of power [€/MW]
    ep_costs_CHP = economics.annuity(
        capex=param_value['capex_CHP'],
        n=param_value['lifetime_CHP'],
        wacc=param_value['wacc_CHP'])

    # Add CHP with its technical specifications to the energy system
    energysystem.add(ExtractionTurbineCHP(
        label='CHP_01',
        inputs={bgas: solph.Flow(
            investment=solph.Investment(
                ep_costs=(ep_costs_CHP*param_value['conv_factor_full_cond']),
                maximum=1667))},
        outputs={
            bel: solph.Flow(),
            bth: solph.Flow()},
        conversion_factors={
            bel: param_value['conv_factor_bel_CHP'],
            bth: param_value['conv_factor_bth_CHP']},
        conversion_factor_full_condensation={
            bel: param_value['conv_factor_full_cond']}))

    # Peak load gas boiler
    # Calculate annuity per installed unit of power [€/MW]
    ep_costs_boiler = economics.annuity(
        capex=param_value['capex_boiler'],
        n=param_value['lifetime_boiler'],
        wacc=param_value['wacc_boiler'])

    # Add boiler with its technical specifications to the energy system
    energysystem.add(solph.Transformer(
        label='boiler',
        inputs={bgas: solph.Flow()},
        outputs={bth: solph.Flow(investment=solph.Investment(
            ep_costs=ep_costs_boiler))},
        conversion_factors={bth: param_value['conversion_factor_boiler']}))

    ep_costs_p2h = economics.annuity(
        capex=param_value['capex_p2h'],
        n=param_value['lifetime_p2h'],
        wacc=param_value['wacc_p2h'])

    energysystem.add(solph.Transformer(
        label='P2H',
        inputs={bel_residual: solph.Flow()},
        outputs={bth: solph.Flow(investment=solph.Investment(
            ep_costs=ep_costs_p2h))},
        conversion_factors={bth: param_value['conversion_factor_p2h']}))

    ep_costs_TES = economics.annuity(
        capex=(param_value['capex_TES']*param_value['TES_capex_variation']),
        n=param_value['lifetime_TES'],
        wacc=param_value['wacc_TES'])
    storage_th = solph.components.GenericStorage(
        label='storage_th',
        inputs={bth: solph.Flow()},
        outputs={bth: solph.Flow()},
        capacity_loss=param_value['capacity_loss_storage_th'],
        initial_capacity=param_value['init_capacity_storage_th'],
        inflow_conversion_factor=param_value['inflow_conv_factor_storage_th'],
        outflow_conversion_factor=param_value[
            'outflow_conv_factor_storage_th'],
        invest_relation_input_capacity=1/param_value[
            'charging_time_storage_th'],
        invest_relation_output_capacity=1/param_value[
            'charging_time_storage_th'],
        investment=solph.Investment(ep_costs=ep_costs_TES))
    energysystem.add(storage_th)

    ep_costs_EES = economics.annuity(
        capex=param_value['capex_EES']*param_value['EES_capex_variation'],
        n=param_value['lifetime_EES'],
        wacc=param_value['wacc_EES'])

    storage_el = solph.components.GenericStorage(
        label='storage_el',
        inputs={bel: solph.Flow()},
        outputs={bel: solph.Flow()},
        capacity_loss=param_value['capacity_loss_storage_el'],
        initial_capacity=param_value['init_capacity_storage_el'],
        inflow_conversion_factor=param_value['inflow_conv_factor_storage_el'],
        outflow_conversion_factor=param_value[
            'outflow_conv_factor_storage_el'],
        invest_relation_input_capacity=1 / param_value[
            'charging_time_storage_el'],
        invest_relation_output_capacity=1 / param_value[
            'charging_time_storage_el'],
        investment=solph.Investment(ep_costs=ep_costs_EES))
    energysystem.add(storage_el)

    ##########################################################################
    # Optimise the energy system and store the results
    ##########################################################################

    logging.info('Optimise the energy system')

    model = solph.Model(energysystem)

    if debug:
        lpfile_name = 'flexCHP_scenario_{0}.lp'.format(variation_nr)
        filename = os.path.join(
            helpers.extend_basic_path('lp_files'), lpfile_name)
        logging.info('Store lp-file in {0}.'.format(filename))
        model.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

    logging.info('Store the energy system with the results.')

    energysystem.results['main'] = outputlib.processing.results(model)
    energysystem.results['meta'] = outputlib.processing.meta_results(model)
    if cfg['price_el_quadratic']:
        energysystem.dump(
            dpath=(abs_path + "/results/optimisation_results/dumps/"
                              "quadratic_price_relationship"),
            filename=(cfg['filename_dumb']+'_scenario_{0}.oemof'.
                      format(variation_nr)))
    if cfg['price_el_quadratic'] == False:
        energysystem.dump(
            dpath=(abs_path + "/results/optimisation_results/dumps/"
                              "linear_price_relationship"),
            filename=(cfg['filename_dumb']+'_scenario_{0}.oemof'.format(
                variation_nr)))
Beispiel #21
0
def write_lp_file():
    filename = os.path.join(
        helpers.extend_basic_path('lp_files'), 'variable_chp.lp')
    logging.info('Store lp-file in {0}.'.format(filename))
    om.write(filename, io_options={'symbolic_solver_labels': True})
Beispiel #22
0
def berlin_model(berlin_e_system):
    """

    Parameters
    ----------
    berlin_e_system : solph.EnergySystem

    Returns
    -------

    """
    time_index = berlin_e_system.time_idx
    p = preferences.Basic()
    d = preferences.Data()

    logging.info("Adding objects to the energy system...")

    # Electricity
    solph.Bus(label='bus_el')

    heat_demand = heat.DemandHeat(time_index)
    heating_systems = [s for s in heat_demand.get().columns if "frac_" in s]

    remove_string = 'frac_'
    heat_demand.demand_by('total_loss_pres',
                          heating_systems,
                          d.bt_dict,
                          remove_string,
                          percentage=True)

    heat_demand.df = heat_demand.dissolve('bezirk', 'demand_by', index=True)

    heat_demand.df = heat_demand.df.rename(
        columns={
            k: k.replace('frac_', '')
            for k in heat_demand.df.columns.get_level_values(1)
        })

    for t in p.types:
        heat_demand.df[t] = (
            heat_demand.df[t].multiply(
                d.sanierungsanteil[t] * d.sanierungsreduktion[t]) +
            heat_demand.df[t].multiply(1 - d.sanierungsanteil[t])) * 1000

    ep = dict()
    ep['basic'] = pd.read_csv('/home/uwe/e_p.csv', ';')
    ep['stromanteil'] = pd.read_csv('/home/uwe/stromanteil_e_p.csv', ';')

    fraction_heating_system_saniert = {
        'off-peak_electricity_heating': 0,
        'district_heating': 0.6,
        'natural_gas_heating': 0.4,
        'oil_heating': 0.4,
        'coal_stove': 0,
        'wp': 1,
    }

    fraction_electrical_dhw = {
        'off-peak_electricity_heating': 1,
        'district_heating': 0.11,
        'natural_gas_heating': 0.09,
        'oil_heating': 0.58,
        'coal_stove': 1,
        'wp': 0,
    }
    ep_mix = dict()
    for e in ep.keys():
        ep_mix[e] = dict()
        for b in p.types:
            ep_mix[e][b] = dict()
            cols = [x.replace('_int_DHW', '') for x in ep[e].columns]
            cols = set([x.replace('_el_DHW', '') for x in cols])
            cols.remove('gtype')
            cols.remove('building')
            cols.remove('heating_system')
            for h in cols:
                tmp = dict()
                for bs in ['saniert', 'unsaniert']:
                    tmp[bs] = dict()
                    for hs in ['saniert', 'unsaniert']:
                        qu = 'gtype=="{0}"'.format(b.upper())
                        qu += ' and building=="{0}"'.format(bs)
                        qu += ' and heating_system=="{0}"'.format(hs)
                        # Mix internal DHW and electrical DHW
                        ep[e].ix[(ep[e].gtype == b.upper()) &
                                 (ep[e].building == bs) &
                                 (ep[e].heating_system == hs),
                                 h] = (ep[e].query(qu)[h + '_int_DHW'] *
                                       (1 - fraction_electrical_dhw[h]) +
                                       ep[e].query(qu)[h + '_el_DHW'] *
                                       fraction_electrical_dhw[h])
                        tmp[bs][hs] = ep[e].query(qu)[h]
                ep_mix[e][b][h] = (
                    float(tmp['saniert']['saniert']) * d.sanierungsanteil[b] *
                    fraction_heating_system_saniert[h] +
                    float(tmp['saniert']['unsaniert']) *
                    d.sanierungsanteil[b] *
                    (1 - fraction_heating_system_saniert[h]) +
                    float(tmp['unsaniert']['saniert']) *
                    (1 - d.sanierungsanteil[b]) *
                    fraction_heating_system_saniert[h] +
                    float(tmp['unsaniert']['unsaniert']) *
                    (1 - d.sanierungsanteil[b]) *
                    (1 - fraction_heating_system_saniert[h]))

    add_dict = {
        'district_dz': 'district_heating',
        'district_z': 'district_heating',
        'bhkw': 'district_heating',
    }

    for e in ep_mix.keys():
        for b in ep_mix[e].keys():
            for new_key in add_dict.keys():
                ep_mix[e][b][new_key] = ep_mix[e][b][add_dict[new_key]]

    # Add heating systems
    sum_wp = 6.42e+10  # Bei 2000 Volllaststunden
    sum_bhkw = 6.75e+11  # Bei 2000 Volllaststunden
    # sum_wp = 50e+9
    # sum_bhkw = 50e+9
    sum_existing = heat_demand.df.sum().sum()
    reduction = (sum_existing - (sum_wp + sum_bhkw)) / sum_existing
    frac_mfh = heat_demand.df.mfh.sum().sum() / heat_demand.df.sum().sum()
    new = {
        'efh': {
            'wp': sum_wp * (1 - frac_mfh),
            'bhkw': sum_bhkw * (1 - frac_mfh)
        },
        'mfh': {
            'wp': sum_wp * frac_mfh,
            'bhkw': sum_bhkw * frac_mfh
        }
    }
    heat_demand.df *= reduction

    # Join some categories
    ol = d.other_demand.pop('oil_light')
    oh = d.other_demand.pop('oil_heavy')
    oo = d.other_demand.pop('oil_other')
    for c in ['ghd', 'i']:
        d.other_demand['oil_heating'][c] = ol[c] + oh[c] + oo[c]
        d.other_demand['natural_gas_heating'][c] += d.other_demand[
            'liquid_gas'][c]
    d.other_demand.pop('liquid_gas')

    heat_demand.df.sortlevel(axis='columns', inplace=True)
    # noinspection PyTypeChecker
    district_z = heat_demand.df.loc[:, (slice(None),
                                        'district_heating')].multiply(
                                            d.fw_verteilung, axis=0).sum()
    # noinspection PyTypeChecker
    district_dz = heat_demand.df.loc[:,
                                     (slice(None),
                                      'district_heating')].multiply(
                                          (1 - d.fw_verteilung), axis=0).sum()

    dsum = heat_demand.df.sum()

    for b in ['efh', 'mfh']:
        dsum[b, 'district_dz'] = district_dz[b]['district_heating']
        dsum[b, 'district_z'] = district_z[b]['district_heating']
        dsum[b, 'bhkw'] = new[b]['bhkw']
        dsum[b, 'wp'] = new[b]['wp']

    dsum.drop('district_heating', 0, 'second', True)
    dsum.sort_index(inplace=True)

    ew = pd.read_csv('/home/uwe/chiba/RLI/data/stadtnutzung_erweitert.csv')[[
        'ew', 'schluessel_planungsraum'
    ]]
    grp = ew.schluessel_planungsraum.astype(str).str[:-8]
    grp = grp.apply(lambda x: '{0:0>2}'.format(x))
    ew = ew.groupby(grp).sum().drop('schluessel_planungsraum', 1)
    # dhw_profile = pd.read_csv('/home/uwe/dhw_demand.csv')
    # *ew.sum() * 657
    dhw = ew.sum() * 657000  # 657000 Wh pro EW

    dhw_factor = (dsum.sum().sum() + float(dhw)) / dsum.sum().sum()
    dsum *= dhw_factor

    dfull = d.other_demand
    aux_elec = dict()
    sum_aux = 0
    print(ep_mix)
    for b in dsum.keys().levels[0]:
        for h in dsum[b].keys():
            dfull.setdefault(h, dict())
            aux_elec.setdefault(h, dict())
            aux_elec[h][b] = (dsum[b][h] * ep_mix['basic'][b][h] *
                              ep_mix['stromanteil'][b][h] / 100)
            print("{:.2E}".format(aux_elec[h][b]))
            sum_aux += aux_elec[h][b]
            dfull[h][b] = dsum[b][h] * ep_mix['basic'][b][h] - aux_elec[h][b]
    # print(dfull)
    # e = 0
    # for a in dfull.keys():
    #     for b in dfull[a].keys():
    #         if b in ['i']:
    #             print(a, b, dfull[a][b])
    #             e += dfull[a][b]
    # print(e)
    # exit(0)
    create_objects.heating_systems(berlin_e_system, dfull, aux_elec, p)

    mylist = list(berlin_e_system.groups.items())
    # Add excess and slack for every BUS

    for k, g in mylist:
        if isinstance(g, solph.Bus):
            solph.Sink(label='excess_{0}'.format(k),
                       inputs={g: solph.Flow(variable_costs=9000)})
            solph.Source(label='slack_{0}'.format(k),
                         outputs={g: solph.Flow(variable_costs=9000)})
    # slacks = ['bus_el', 'bus_district_z', 'bus_district_dz']
    # for s in slacks:
    #     obj = berlin_e_system.groups[s]
    #     solph.Source(label='slack_{0}'.format(s),
    #                  outputs={obj: solph.Flow(variable_costs=9000)})

    # sources
    source_costs = {
        'lignite': 90,
        'natural_gas': 120,
        'fuel_bio': 150,
        'solar_thermal': 0,
        'biomass': 140,
        'oil': 130,
        'coal': 100
    }

    for src in source_costs:
        if 'bus_' + src in berlin_e_system.groups:
            solph.Source(label=src,
                         outputs={
                             berlin_e_system.groups['bus_' + src]:
                             solph.Flow(variable_costs=source_costs[src])
                         })
        else:
            logging.warning("No need for a {0} source.".format(src))

    # import pprint as pp
    # pp.pprint(berlin_e_system.groups)

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(berlin_e_system)

    filename = os.path.join(helpers.extend_basic_path('lp_files'),
                            'storage_invest.lp')
    logging.info('Store lp-file in {0}.'.format(filename))
    om.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    om.solve(solver='gurobi', solve_kwargs={'tee': True})

    berlin_e_system.dump('/home/uwe/')
    return berlin_e_system
Beispiel #23
0
def run_model(config_path, team_number):

    with open(config_path, 'r') as ymlfile:
        cfg = yaml.load(ymlfile, Loader=yaml.CLoader)

    if cfg['debug']:
        number_of_time_steps = 3
    else:
        number_of_time_steps = 8760

    solver = cfg['solver']
    debug = cfg['debug']
    periods = number_of_time_steps
    solver_verbose = cfg['solver_verbose']  # show/hide solver output

    logger.define_logging(logfile='model_team_{0}.log'.format(team_number + 1),
                          screen_level=logging.INFO,
                          file_level=logging.DEBUG)

    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2019',
                                    periods=number_of_time_steps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    #    timestr = time.strftime("%Y%m%d")

    ##########################################################################
    # Einlesen der Zeitreihen und Variablen aus den Dateien
    ##########################################################################

    abs_path = os.path.dirname(os.path.abspath(os.path.join(__file__, '..')))

    file_path_ts = abs_path + '/data_raw/' + cfg['time_series_file_name']
    data = pd.read_csv(file_path_ts, sep=';')

    file_name_param_01 = cfg['design_parameters_file_name'][team_number]
    file_path_param_01 = (abs_path + '/data/' + file_name_param_01)
    param_df_01 = pd.read_csv(file_path_param_01,
                              index_col=1,
                              sep=';',
                              encoding='unicode_escape')
    param_value = param_df_01['value']

    # periodische Kosten
    epc_PV = economics.annuity(capex=param_value['capex_PV'],
                               n=param_value['n_PV'],
                               wacc=param_value['wacc'])
    epc_Solarthermie = economics.annuity(capex=param_value['capex_Sol'],
                                         n=param_value['n_Sol'],
                                         wacc=param_value['wacc'])
    epc_gas_boiler = economics.annuity(capex=param_value['capex_Gaskessel'],
                                       n=param_value['n_Gaskessel'],
                                       wacc=param_value['wacc'])
    epc_BHKW = economics.annuity(capex=param_value['capex_BHKW'],
                                 n=param_value['n_BHKW'],
                                 wacc=param_value['wacc'])
    epc_heat_pump = economics.annuity(capex=param_value['capex_Waermepumpe'],
                                      n=param_value['n_Waermepumpe'],
                                      wacc=param_value['wacc'])
    epc_el_storage = economics.annuity(
        capex=param_value['capex_Stromspeicher'],
        n=param_value['n_Stromspeicher'],
        wacc=param_value['wacc'])
    epc_th_storage = economics.annuity(
        capex=param_value['capex_Waermespeicher'],
        n=param_value['n_Waermespeicher'],
        wacc=param_value['wacc'])

    ##########################################################################
    # Erstellung der Oemof-Komponenten
    ##########################################################################

    logging.info('Create oemof objects')

    ### Definition der bus'es #################################################

    # Erdgasbus
    b_gas = solph.Bus(label="Erdgas")

    # Strombus
    b_el = solph.Bus(label="Strom")

    # Waermebus
    b_th = solph.Bus(label="Waerme")

    # Hinzufügen zum Energiesystem
    energysystem.add(b_gas, b_el, b_th)

    ### Definition des Ueberschusses #########################################

    # Senke fuer Stromueberschusss
    energysystem.add(
        solph.Sink(label='excess_bel', inputs={b_el: solph.Flow()}))

    # Senke fuer Waermeueberschuss
    energysystem.add(
        solph.Sink(label='excess_bth', inputs={b_th: solph.Flow()}))

    ### Definition Quellen #################################################

    # Quelle: Erdgasnetz
    energysystem.add(
        solph.Source(label='Gasnetz',
                     outputs={
                         b_gas:
                         solph.Flow(variable_costs=param_value['vc_gas'] +
                                    param_value['vc_CO2'])
                     }))  #[€/kWh]

    # Quelle: Stromnetz
    energysystem.add(
        solph.Source(label='Strombezug',
                     outputs={
                         b_el: solph.Flow(variable_costs=param_value['vc_el'])
                     }))  #[€/kWh]

    # Quelle: Waermenetz/Fernwaerme
    energysystem.add(
        solph.Source(label='Waermebezug',
                     outputs={
                         b_th: solph.Flow(variable_costs=param_value['vc_th'])
                     }))  #[€/kWh]

    # Quelle: Solaranlage
    if param_value['A_Kollektor_gesamt'] > 0:
        energysystem.add(
            solph.Source(
                label='PV',
                outputs={
                    b_el:
                    solph.Flow(
                        actual_value=(data['Sol_irradiation [Wh/sqm]'] *
                                      0.001 * param_value['cf_PV']),  #[kWh/m²]
                        fixed=True,
                        investment=solph.Investment(
                            ep_costs=epc_PV,
                            minimum=param_value['A_min_PV'] * 1 *
                            param_value['cf_PV']))
                }))

    # Quelle: Solarthermieanlage
    if param_value['A_Kollektor_gesamt'] > 0:
        energysystem.add(
            solph.Source(
                label='Solarthermie',
                outputs={
                    b_th:
                    solph.Flow(
                        actual_value=(data['Sol_irradiation [Wh/sqm]'] *
                                      0.001 *
                                      param_value['cf_Sol']),  #[kWh/m²]
                        fixed=True,
                        investment=solph.Investment(
                            ep_costs=epc_Solarthermie,
                            minimum=param_value['A_min_Sol'] * 1 *
                            param_value['cf_Sol']))
                }))

    ### Definition Bedarf ################################################

    # Strombedarf
    energysystem.add(
        solph.Sink(
            label='Strombedarf',
            inputs={
                b_el:
                solph.Flow(
                    actual_value=data['P*'],
                    nominal_value=param_value['W_el'],  #[kWh]
                    fixed=True)
            }))

    # Waermebedarf
    energysystem.add(
        solph.Sink(
            label='Waermebedarf',
            inputs={
                b_th:
                solph.Flow(
                    actual_value=data['Q*'],
                    nominal_value=param_value['W_th'],  #[kWh]
                    fixed=True)
            }))

    ### Definition Systemkomponenten #########################################

    # Transformer: Gaskessel
    if param_value['max_Gaskessel'] > 0:
        energysystem.add(
            solph.Transformer(
                label="Gaskessel",
                inputs={b_gas: solph.Flow()},
                outputs={
                    b_th:
                    solph.Flow(investment=solph.Investment(
                        ep_costs=epc_gas_boiler,
                        minimum=param_value['min_Gaskessel'],  #[kW]
                        maximum=param_value['max_Gaskessel']))
                },  #[kW]
                conversion_factors={b_th: param_value['cf_Gaskessel']}))

    # Transformer: BHKW
    if param_value['max_BHKW'] > 0:
        energysystem.add(
            solph.Transformer(
                label="BHKW",
                inputs={b_gas: solph.Flow()},
                outputs={
                    b_el:
                    solph.Flow(),
                    b_th:
                    solph.Flow(investment=solph.Investment(
                        ep_costs=epc_BHKW,
                        minimum=param_value['min_BHKW'],  #[kW]
                        maximum=param_value['max_BHKW']))
                },  #[kW]
                conversion_factors={
                    b_el: param_value['cf_BHKW_el'],
                    b_th: 0.85 - param_value['cf_BHKW_el']
                }))

    # Transformer: Waermepumpe
    if param_value['max_Waermepumpe'] > 0:
        energysystem.add(
            solph.Transformer(
                label="Waermepumpe",
                inputs={b_el: solph.Flow()},
                outputs={
                    b_th:
                    solph.Flow(investment=solph.Investment(
                        ep_costs=epc_heat_pump,
                        minimum=param_value['min_Waermepumpe'],  #[kW]
                        maximum=param_value['max_Waermepumpe']))
                },  #[kW]
                conversion_factors={b_th: param_value['COP_Waermepumpe']}))

    # Speicher: Stromspeicher
    if param_value['max_Stromspeicher'] > 0:
        Stromspeicher = solph.components.GenericStorage(
            label='Stromspeicher',
            inputs={b_el: solph.Flow()},
            outputs={b_el: solph.Flow()},
            loss_rate=param_value['lr_Stromspeicher'],
            initial_storage_level=param_value['isl_Stromspeicher'],
            inflow_conversion_factor=param_value['cf_Stromspeicher_ein'],
            outflow_conversion_factor=param_value['cf_Stromspeicher_aus'],
            investment=solph.Investment(
                ep_costs=epc_el_storage,
                minimum=param_value['min_Stromspeicher'],  #[kWh]
                maximum=param_value['max_Stromspeicher']))  #[kWh]
        energysystem.add(Stromspeicher)

    # Speicher: Waermespeicher
    if param_value['max_Waermespeicher'] > 0:
        Waermespeicher = solph.components.GenericStorage(
            label='Waermespeicher',
            inputs={b_th: solph.Flow()},
            outputs={b_th: solph.Flow()},
            loss_rate=param_value['lr_Waermespeicher'],
            initial_storage_level=param_value['isl_Waermespeicher'],
            inflow_conversion_factor=param_value['cf_Waermespeicher_ein'],
            outflow_conversion_factor=param_value['cf_Waermespeicher_aus'],
            investment=solph.Investment(
                ep_costs=epc_th_storage,
                minimum=param_value['min_Waermespeicher'],  #[kWh]
                maximum=param_value['max_Waermespeicher']))  #[kWh]
        energysystem.add(Waermespeicher)

    logging.info('Optimise the energy system')

    # Initialisierung des Modells
    model = solph.Model(energysystem)

    ##########################################################################
    # Constraint fuer Kollektorgesamtflaeche
    ##########################################################################

    PV_installed = energysystem.groups['PV']
    Sol_installed = energysystem.groups['Solarthermie']

    myconstrains = po.Block()
    model.add_component('MyBlock', myconstrains)
    myconstrains.collector_area = po.Constraint(expr=(
        (((model.InvestmentFlow.invest[PV_installed, b_el]) /
          (1 * param_value['cf_PV'])) +
         ((model.InvestmentFlow.invest[Sol_installed, b_th]) /
          (1 * param_value['cf_Sol']))) <= param_value['A_Kollektor_gesamt']))

    ##########################################################################
    # Optimierung des Systems und Speichern des Ergebnisses
    ##########################################################################
    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'model_team_{0}.lp'.format(team_number + 1))
        logging.info('Store lp-file in {0}.'.format(filename))
        model.write(filename, io_options={'symbolic_solver_labels': True})

    # if tee_switch is true solver messages will be displayed
    logging.info(
        'Solve the optimization problem of team {0}'.format(team_number + 1))
    model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})

    logging.info('Store the energy system with the results.')

    # add results to the energy system to make it possible to store them.
    energysystem.results['main'] = outputlib.processing.results(model)
    energysystem.results['meta'] = outputlib.processing.meta_results(model)
    results = energysystem.results['main']

    energysystem.dump(dpath=abs_path + "/results",
                      filename="model_team_{0}.oemof".format(team_number + 1))
Beispiel #24
0
def optimise_storage_size(filename="storage_invest.csv",
                          solvername='cbc',
                          debug=True,
                          number_timesteps=8760,
                          tee_switch=True):
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/' + str(year),
                                    periods=number_timesteps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    # Read data file
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")
    data_demand = data['demand_el'] / data['demand_el'].sum()

    ##########################################################################
    # Create oemof object
    ##########################################################################
    consumption = 5165 * 1e6
    wind_installed = 1516 * 1e3
    pv_installed = 1491 * 1e3
    grid_share = 0.75

    logging.info('Create oemof objects')
    # create gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # create excess component for the electricity bus to allow overproduction
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})

    # Create commodity object for import electricity resource
    solph.Source(label='gridsource',
                 outputs={
                     bel:
                     solph.Flow(nominal_value=consumption * grid_share *
                                number_timesteps / 8760,
                                summed_max=1)
                 })

    # create fixed source object for wind
    solph.Source(label='wind',
                 outputs={
                     bel:
                     solph.Flow(actual_value=wind_feedin,
                                nominal_value=wind_installed,
                                fixed=True,
                                fixed_costs=20)
                 })

    # create fixed source object for pv
    solph.Source(label='pv',
                 outputs={
                     bel:
                     solph.Flow(actual_value=pv_feedin,
                                nominal_value=pv_installed,
                                fixed=True,
                                fixed_costs=15)
                 })

    # create simple sink object for demand
    solph.Sink(label='demand',
               inputs={
                   bel:
                   solph.Flow(actual_value=data_demand,
                              fixed=True,
                              nominal_value=consumption)
               })

    # Calculate ep_costs from capex to compare with old solph
    capex = 1000
    lifetime = 20
    wacc = 0.05
    epc = capex * (wacc * (1 + wacc)**lifetime) / ((1 + wacc)**lifetime - 1)

    # create storage transformer object for storage
    solph.Storage(
        label='storage',
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.Flow(variable_costs=10e10)},
        capacity_loss=0.00,
        initial_capacity=0,
        nominal_input_capacity_ratio=1,
        nominal_output_capacity_ratio=1,
        inflow_conversion_factor=1,
        outflow_conversion_factor=0.8,
        fixed_costs=35,
        investment=solph.Investment(ep_costs=epc),
    )

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(energysystem)

    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'storage_invest.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    om.solve(solver=solvername, solve_kwargs={'tee': tee_switch})

    return energysystem
Beispiel #25
0
def optimise_storage_size(filename="storage_investment.csv",
                          solver='cbc',
                          debug=True,
                          number_timesteps=8760,
                          tee_switch=True):
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2012',
                                    periods=number_timesteps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    # Read data file
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')
    # create natural gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # create excess component for the electricity bus to allow overproduction
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})

    # create source object representing the natural gas commodity (annual limit)
    solph.Source(label='rgas',
                 outputs={
                     bgas:
                     solph.Flow(nominal_value=194397000 * number_timesteps /
                                8760,
                                summed_max=1)
                 })

    # create fixed source object representing wind power plants
    solph.Source(label='wind',
                 outputs={
                     bel:
                     solph.Flow(actual_value=data['wind'],
                                nominal_value=1000000,
                                fixed=True,
                                fixed_costs=20)
                 })

    # create fixed source object representing pv power plants
    solph.Source(label='pv',
                 outputs={
                     bel:
                     solph.Flow(actual_value=data['pv'],
                                nominal_value=582000,
                                fixed=True,
                                fixed_costs=15)
                 })

    # create simple sink object representing the electrical demand
    solph.Sink(label='demand',
               inputs={
                   bel:
                   solph.Flow(actual_value=data['demand_el'],
                              fixed=True,
                              nominal_value=1)
               })

    # create simple transformer object representing a gas power plant
    solph.LinearTransformer(
        label="pp_gas",
        inputs={bgas: solph.Flow()},
        outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)},
        conversion_factors={bel: 0.58})

    # If the period is one year the equivalent periodical costs (epc) of an
    # investment are equal to the annuity. Use oemof's economic tools.
    epc = economics.annuity(capex=1000, n=20, wacc=0.05)

    # create storage object representing a battery
    solph.Storage(
        label='storage',
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.Flow(variable_costs=10e10)},
        capacity_loss=0.00,
        initial_capacity=0,
        nominal_input_capacity_ratio=1 / 6,
        nominal_output_capacity_ratio=1 / 6,
        inflow_conversion_factor=1,
        outflow_conversion_factor=0.8,
        fixed_costs=35,
        investment=solph.Investment(ep_costs=epc),
    )

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    # initialise the operational model
    om = solph.OperationalModel(energysystem)

    # if debug is true an lp-file will be written
    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'storage_invest.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    # if tee_switch is true solver messages will be displayed
    logging.info('Solve the optimization problem')
    om.solve(solver=solver, solve_kwargs={'tee': tee_switch})

    return energysystem
Beispiel #26
0
def define_logging(logpath=None,
                   logfile='oemof.log',
                   file_format=None,
                   screen_format=None,
                   file_datefmt=None,
                   screen_datefmt=None,
                   screen_level=logging.INFO,
                   file_level=logging.DEBUG,
                   log_version=True,
                   log_path=True,
                   timed_rotating=None):
    r"""Initialise customisable logger.

    Parameters
    ----------
    logfile : str
        Name of the log file, default: oemof.log
    logpath : str
        The path for log files. By default a ".oemof' folder is created in your
        home directory with subfolder called 'log_files'.
    file_format : str
        Format of the file output.
        Default: "%(asctime)s - %(levelname)s - %(module)s - %(message)s"
    screen_format : str
        Format of the screen output.
        Default: "%(asctime)s-%(levelname)s-%(message)s"
    file_datefmt : str
        Format of the datetime in the file output. Default: None
    screen_datefmt : str
        Format of the datetime in the screen output. Default: "%H:%M:%S"
    screen_level : int
        Level of logging to stdout. Default: 20 (logging.INFO)
    file_level : int
        Level of logging to file. Default: 10 (logging.DEBUG)
    log_version : boolean
        If True the actual version or commit is logged while initialising the
        logger.
    log_path : boolean
        If True the used file path is logged while initialising the logger.
    timed_rotating : dict
        Option to pass parameters to the TimedRotatingFileHandler.


    Returns
    -------
    str : Place where the log file is stored.

    Notes
    -----
    By default the INFO level is printed on the screen and the DEBUG level
    in a file, but you can easily configure the logger.
    Every module that wants to create logging messages has to import the
    logging module. The oemof logger module has to be imported once to
    initialise it.

    Examples
    --------
    To define the default logger you have to import the python logging
    library and this function. The first logging message should be the
    path where the log file is saved to.

    >>> import logging
    >>> from oemof.tools import logger
    >>> mypath = logger.define_logging(
    ...     log_path=True, log_version=True, timed_rotating={'backupCount': 4},
    ...     screen_level=logging.ERROR, screen_datefmt = "no_date")
    >>> mypath[-9:]
    'oemof.log'
    >>> logging.debug("Hallo")
    """

    if logpath is None:
        logpath = helpers.extend_basic_path('log_files')

    file = os.path.join(logpath, logfile)

    log = logging.getLogger('')

    # Remove existing handlers to avoid interference.
    log.handlers = []
    log.setLevel(logging.DEBUG)

    if file_format is None:
        file_format = (
            "%(asctime)s - %(levelname)s - %(module)s - %(message)s")
    file_formatter = logging.Formatter(file_format, file_datefmt)

    if screen_format is None:
        screen_format = "%(asctime)s-%(levelname)s-%(message)s"
    if screen_datefmt is None:
        screen_datefmt = "%H:%M:%S"
    screen_formatter = logging.Formatter(screen_format, screen_datefmt)

    tmp_formatter = logging.Formatter("%(message)s")

    ch = logging.StreamHandler(sys.stdout)
    ch.setFormatter(screen_formatter)
    ch.setLevel(screen_level)
    log.addHandler(ch)

    timed_rotating_p = {'when': 'midnight', 'backupCount': 10}

    if timed_rotating is not None:
        timed_rotating_p.update(timed_rotating)

    fh = handlers.TimedRotatingFileHandler(file, **timed_rotating_p)
    fh.setFormatter(tmp_formatter)
    fh.setLevel(file_level)
    log.addHandler(fh)

    logging.debug("******************************************************")
    fh.setFormatter(file_formatter)
    if log_path:
        logging.info("Path for logging: {0}".format(file))

    if log_version:
        logging.info("Used oemof version: {0}".format(get_version()))
    return file
def optimise_storage_size(filename="storage_invest.csv", solvername='cbc',
                          debug=True, number_timesteps=8760, tee_switch=True):
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/' + str(year), periods=number_timesteps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    # Read data file
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")
    data_demand = data['demand_el']/data['demand_el'].sum()

    ##########################################################################
    # Create oemof object
    ##########################################################################
    consumption = 2255 * 1e6
    wind_installed = 1000 * 1e3
    pv_installed = 582 * 1e3
    grid_share = 0.05

    logging.info('Create oemof objects')
    # create gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # create excess component for the electricity bus to allow overproduction
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})

    # Create commodity object for import electricity resource
    solph.Source(label='gridsource', outputs={bel: solph.Flow(
        nominal_value=consumption * grid_share * number_timesteps / 8760,
        summed_max=1)})

    # create fixed source object for wind
    solph.Source(label='wind', outputs={bel: solph.Flow(
        actual_value=wind_feedin, nominal_value=wind_installed, fixed=True,
        fixed_costs=20)})

    # create fixed source object for pv
    solph.Source(label='pv', outputs={bel: solph.Flow(
        actual_value=pv_feedin, nominal_value=pv_installed, fixed=True,
        fixed_costs=15)})

    # create simple sink object for demand
    solph.Sink(label='demand', inputs={bel: solph.Flow(
        actual_value=data_demand, fixed=True, nominal_value=consumption)})

    # Calculate ep_costs from capex to compare with old solph
    capex = 1000
    lifetime = 20
    wacc = 0.05
    epc = capex * (wacc * (1 + wacc) ** lifetime) / ((1 + wacc) ** lifetime - 1)

    # create storage transformer object for storage
    solph.Storage(
        label='storage',
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.Flow(variable_costs=10e10)},
        capacity_loss=0.00, initial_capacity=0,
        nominal_input_capacity_ratio=1,
        nominal_output_capacity_ratio=1,
        inflow_conversion_factor=1, outflow_conversion_factor=0.8,
        fixed_costs=35,
        investment=solph.Investment(ep_costs=epc),
    )

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(energysystem)

    if debug:
        filename = os.path.join(
            helpers.extend_basic_path('lp_files'), 'storage_invest.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    logging.info('Solve the optimization problem')
    om.solve(solver=solvername, solve_kwargs={'tee': tee_switch})

    return energysystem