Giter VIP home page Giter VIP logo

oemof-solph's Introduction

Open Energy Modelling Framework (oemof)

The Open Energy Modelling Framework (oemof) is a Python toolbox for energy system modelling and optimisation.

The oemof project aims to be a loose organisational frame for tools in the wide field of (energy) system modelling. Every project is managed by their own developer team but we share some developer and design rules to make it easier to understand each other's tools. All project libraries are free software licenced under the MIT license.

All projects are in different stages of implementation, some even may not have a stable release, but all projects are open to be joined by interested people. We do not belong to a specific institution and everybody is free to join the developer teams and will have the same rights. There is no higher decision level.

oemof community

This repository is also used to organise everything for the oemof community.

  • Webconference dates
  • Real life meetings
  • Website and Mailinglist
  • General communication

You can find recent topics of discussion in the issues.

Real life meetings

The oemof community meets in person on a regular basis. Find the latest information on the next meeting(s) on this wiki page: https://github.com/oemof/oemof/wiki

oemof-solph's People

Contributors

antonellaconsolinno avatar bachibouzouk avatar birgits avatar bmlancien avatar c-moeller avatar ckaldemeyer avatar dfuh avatar e-zolotarevskaya avatar fabiantu avatar franzipl avatar fwitte avatar gnn avatar gplssm avatar henhuy avatar jnnr avatar jokochems avatar joroeder avatar lensum avatar lmilletb avatar magering avatar nailend avatar nesnoj avatar p-snft avatar pkassing avatar sasa821 avatar simnh avatar srhbrnds avatar steffengit avatar tobirohrer avatar uvchik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oemof-solph's Issues

No investment in sources when add_out_limit is omitted

When I run the storage_invest.py with

source.FixedSource.optimization_options.update({'investment': True})

and no add_out_limit in the FixedSources pv and wind I get the following in lp file

0 <= _class__oemof_core_network_entities_components_sources_FixedSource___add_out(pv) <= 0
0 <= _class__oemof_core_network_entities_components_sources_FixedSource___add_out(wind) <= 0

which is wrong in my opinion since there is no possibility for the add_out variable to increase.

When I then in addition set out_max=[0] I get an infeasible problem as there can't be any generation capacity to meet the demand.

I pushed the modified storage_invest.py to the branch 'fix_invest_sources'.

Automatically register entities

Every Entity instance created should automatically be added to the entities attribute of an existing EnergySystem instance.
See also #19.

Creating a logging file

With commit 37afe31 one can use a helping function to initialise a logger within oemof.

Just import the logger module and initialise the logger at the very beginning of your app.

# Import logging module
from oemof.tools import logger

# initialise the logger
logger.define_logging()

Now everything higher than info will be displayed on the screen but everything (including debug) will be written to a logfile in the folder: ~/.oemof/log_files/

Of course you are able to customise this behaviour. For example if want just warnings and errors but no infos on the screen.

The screen output looks like this now:

11:40:24-INFO-Path for logging: /home/uwe/.oemof/log_files
11:40:24-INFO-Used oemof version: 18345077 @ features/two_region_example
11:40:25-INFO-Processing region: Landkreis Wittenberg (LanWit)
11:40:26-WARNING-Something odd happened...

The file output looks like this:

2015-12-10 11:41:14,628 - INFO - logger - Path for logging: /home/uwe/.oemof/log_files
2015-12-10 11:41:14,628 - INFO - logger - Used oemof version: 18345077 @ features/two_region_example
2015-12-10 11:41:14,693 - DEBUG - tools - Getting polygon from DB
2015-12-10 11:41:14,694 - INFO - two_regions_example - Processing region: Landkreis Wittenberg (LanWit)
2015-12-10 11:41:15,591 - DEBUG - models - Retrieving cp values from cp_values.hf5
2015-12-10 11:41:16,987 - WARNING - models - Something odd happened...

@oemof/oemof-main : Do we agree that we want to use logging messages within the code? I like the fact that you have a protocol in a file. This can help a lot while debugging. But than we need meaningful logging messages.

Check example app

Check the scenario in example app and decide if another (or second) example is necessary.

Adding a method to dump/restore attributes from/to an EnergySystem instance

This features is very interesting for testing environments.

If you are fixing a bug in solph for example you can save the time creating the EnergySystem instance again and again.

my_energysystem = es.EnergySystem()
# [...] adding hundreds of entities, attributes and a simulation instance (takes 2 minutes)
my_energysystem.dump() 
my_energysystem.optimize()
# [...] do anything with the results

Within the bug-fix-process you can restore the dump:

my_energysystem = es.EnergySystem()
my_energysystem.restore()  # (takes less than 2 seconds)
my_energysystem.optimize()
# [...] do anything with the results

The dump/restore method creates a logging.debug message and(!) returns the message. So you can just use logging.info(my_energysystem.restore()) or print(my_energysystem.restore()) to get the message on the screen.

Do you think that it should not be a method of the EnergySystem class but a function of the "tools" sub-package? Feedback wanted!

outputlib with pandas - Improvements

Some changes still have to be done. I am using this issue to collect and discuss ideas.

Ideas for changes:

  • It should be possible to pass a result-object directly. For this, we need a way to deal with the datetime-index which normally comes from the energy system
  • Add a flag like "return_df". If set to True, the dataframe-object will be returned directly
  • Add possibility to exclude components in plot_bus() method
  • Add a plot method that gives a good overview about the bus balance. My idea would be a stacked area or a normal stacked stackplot. All inputs are positive and all outputs negative. Additionally, the residual load will be plotted as a line and should be zero.
  • Add methods to store/restore the dataframe using pickle or something equivalent
  • Realize dataframe creation and plotting in different classes (separate data and visualisation)

Usage of Python/oemof-packages

I have just stumpled across an article about a Python workflow using Anaconda: http://stiglerdiet.com/blog/2015/Nov/24/my-python-environment-workflow-with-conda/ .

By the way, I got it from http://www.pythontips.com which is worth outchecking ;-)

So far we are a small crowd of developers mostly working on GNU/Linux and only have a few pure application-users. In the installation HowTo, everything is explained using the systems Python installation which can have some disadvatages when working on different projects, versions, etc.. See the article for more information.

Even if that might not apply for most of us, when I look at the future development and usage of oemof in university courses and seminars, I see long installation parties for different operating systems (Windows, OSX, Linux, ...) coming since the Python distributions, PATH-adjustments, etc. differ a lot among the OSes.

If I get the above article right, all this could be prevented by using the explained workflow since Anaconda is available for all mainstream operating systems. Looking at the license (which is BSD 3-clause: http://docs.continuum.io/anaconda/eula) we shouldn't get into trouble. If we did it like this, our installation HowTo would be comparably lean, similar to Stefan's: http://docs.callio.pe/en/stable/user/installation.html

@oemof/oemof-main What do you think?

Storage model in investment mode: some understanding problems

Hi there,
even though I was involved in the development of the storage functionalities, I still have some problems in understanding.. I have an investment model with storage component and without any constraints concerning upper and lower bounds, so my storage component definition would look like this.. only buses, technical and economic parameters are given:

storage = transformer.Storage(uid='sto_simple',
                              inputs=[bel_hh],
                              outputs=[bel_hh],
                              eta_in=1,
                              eta_out=0.8,
                              cap_loss=0.00,
                              opex_fix=35,
                              opex_var=10e10,
                              capex=1000,
                              cap_initial=0,
                              c_rate_in=1/6,
                              c_rate_out=1/6)

I get this error:

  File "/home/caro/rlihome/Git/oemof_base/oemof/core/network/entities/components/transformers.py", line 170, in __init__
    'Did you specify c_rate_out and cap_max?')
ValueError: Failed to set out_max automatically.Did you specify c_rate_out and cap_max?

.., because I didn't specify cap_max, which is the maximum value of state of charge (as absolute value), means the storage capacity.

As far as I understand, cap_max is necessary here to calculate out_max (c_rate * cap_max), which is the maximum output value in every timestep and an attribute for every component. So I have to either define out_max or cap_max when creating my storage object. But since I have an investment model, those two attributes are variables in my case and I want to let the model calculate them.

I really don't get it :-(
What is my mistake here?

@simonhilpert
@ckaldemeyer

The release of v0.0.2 is coming up soon

The deadline of the December release is the 22nd of December at 8 am.

  • Set the milestone to the next release if you will not be able to close your issue until the deadline of the December release.
  • Add all changes you made (fixes, enhancements,...) to the whatsnew-file and commit them. In the future every merge into the dev branch should contain a change of the whatsnew-file.
  • Merge everything you want to release into the dev branch until the deadline . Later merges/commits will be ignored. Close the related issue.

There should not be any open issue related to the December milestone on the morning of the 22.12.!

Entity does not appear in the EnergySystem object

I created an EnergySystem object and than created a bus. This bus should automatically appear in the entities list of the EnergySystem but it does not.

Do I have to pass the EnergySystem to the entity?

So far it looks like this:

Bus(uid=('bus', 'global', 'coal'), type='coal', price=60, sum_out_limit=10e10)

outputlib - basic plots

Uwe has already started with his outputlib and created a method which creates a dataframe with all component timeseries arround a given bus.

He started with basic matplotlib which has all configuration options but in my opinion sometimes to many for standard plots as it is overwhelming...

After some trying my idea would be to go with the pandas basic plotting functions (based on matplotlib) for the basic plotting functions and the plots for renpass-gis.

Here's a small example with a handfull of plots and some possible configuration options beyond the standard functionalities (needs matplotlib >= 1.4):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from datetime import datetime as dt
mpl.style.use('ggplot')

# Generate sample data
sample_data = np.random.rand(24*365, 5)
df = pd.DataFrame(sample_data,
                  index=pd.date_range('1/1/2015 00:00',
                                      periods=len(sample_data), freq='H'))

# Select date range to plot
date_from = dt(2015, 12, 22, 0, 0)
date_to = dt(2015, 12, 22, 23, 0)
df = df.loc[date_from:date_to]

# Plotting
# Formatting-tuple (title, colormap, xlabel, ...)
# for matplotlib.axes.AxesSubplot object could
# be passed by kwargs later
df.plot(kind='line', colormap='Spectral', title='Line Plot', linewidth='2')
[(ax.set_ylabel("Power in GW"),
 ax.set_xlabel("Date and Time"),
 ax.legend(('Wind', 'PV', 'Biomass', 'RoR', 'Demand'), loc='upper right'))
 for ax in plt.gcf().axes]

df.plot(kind='bar', stacked=True, colormap='Greens', title='Bar Plot')
[ax.legend(loc='upper right') for ax in plt.gcf().axes]

df.plot(kind='barh', stacked=True, colormap='Oranges', title='H-Bar Plot')
[ax.legend(loc='upper right') for ax in plt.gcf().axes]

df.plot(kind='area', stacked=False, alpha=0.5, colormap='Spectral',
        title='Area Plot')
[ax.legend(('Wind', 'PV', 'Biomass', 'RoR', 'Demand'),
           loc='upper right') for ax in plt.gcf().axes]

df.plot(kind='box', colormap='Reds', title='Box Plot')
[ax.legend(loc='upper right') for ax in plt.gcf().axes]

df.loc['2015-12-22 12:00:00':'2015-12-22 18:00:00', 2:3] \
    .plot(kind='hist', stacked=True, bins=20, colormap='ocean',
          title='Histogram of a subset')
[ax.legend(('Col1', 'Col2'), loc='upper right') for ax in plt.gcf().axes]

df.plot(kind='scatter', x=0, y=1,
        title='Scatter Plot (first vs. second column)')
[ax.legend(loc='upper right') for ax in plt.gcf().axes]

It would be quickly implemented on top of Uwes work and should fulfill most needs as I do not want to spend too much time on visualisation tweaking.

@oemof/oemof-main

Whats your opinion on this?

Happy christmas
Cord

Who will be additional owner of in oemof?

Decision wanted from: @oemof/oemof-main .

I think we should add owner with admin rights - e.g. for small changes in between and not only relying on two people.

Who wants to be owner and take some responsibilty for the group-page, as well as this repository on github? I propose @ckaldemeyer .

Should "results_to_objects" be the default post-processing?

At the moment it works like this:

my_energysystem.optimize()
pp.results_to_objects(my_energysystem.optimization_model)

Is it possible to write the results to the object by default and use an optional parameter to prevent it from doing so.

And if we write the results to the object, do we still need the 'optimization_model' attribute. Is it possible to remove it by an optional parameter or does it still holds essential informations?

I would like to dump the EnergySystem object with the results but it does not work if the 'optimization_model' attribute is still there.

Titles oemof and oemof/oemof_base

Hello on github ;-)

Here's my first issue on the titles which I don't find suitable:

"Model of an energy supply system as open framework with modular structure." (oemof)

"open energy modelling framework - an open source model to optimise energy systems" (oemof/oemof_base)

For me oemof is not a model of one (or more) energy supply systems or a model to optimise energy systems but empowers the users to model (different parts) of energy supply systems and optionally provides the possibility to optimise them.

What do you think? I'll make up my mind meanwhile..

Simulation-object for solve-method of optimizationmodel not working from outside energysystem class

At the moment the simulation-object only works in combination with optimize method of the energy_system class. I should work as well from outside the energysystem if the solve method is called for the optimization model.

I added this (removed again) inside the sovle-method of OptimizationModel() in the solph package as an
idea:

        debug = kwargs.get('debug', self.energysystem.simulation.debug)
        duals = kwargs.get('duals', self.energysystem.simulation.duals)
        solver = kwargs.get('solver', self.energysystem.simulation.solver)
        solver_io = kwargs.get('solver_io',
                               self.energysystem.simulation.solver_io)

Implement rolling - optimization in solph

It makes sense to implement a rolling timehorizon for optimization problems in the solph module for two reasons:

  • more realistic results
  • reduction of memory usage for very large problems

Change default repository

You discussed your git workflow on your release meeting and semi-decided in favor of the common git-flow. This flow changes the meaning of the master branch from a "main"-branch to a "latest-release"-branch that is relatively outdated. Yet, it is the first branch that you visit on your git-hub.

It might be useful if you change the default branch from master to develop.

Problem with objective function in storage example

I have taken a look at the objective function in the lp file which is generated when running the storage example (oemof_base/examples/storage_optimization). This looks very strange for me:

min
objective:
+50 w(pp_gas_bel_0)
+50 w(pp_gas_bel_1)
...
+50 w(pp_gas_bel_8760)
+28730000 ONE_VAR_CONSTANT

As far as I can see only opex_var (50) of the gas power plant and a constant variable is considered. What about the storage output? Why is this not part of the objective function?

Also invest variables are missing.

Does anyone know?

Which versions do we want to have at readthedocs (RTD)?

Do we get a decision until the next release? Would be great 😄

  1. Which branches do we want to show?
  2. What should be the default branch?

There is no fall-back at RTD. If somebody links to .../en/dev and this link doesn't exist anymore an error is shown. Therefore I think it is good to decide soon.

Beside the feature branches we can offer documentations for the following branches/labels:

I did not find a way to change the references of latest and stable!

name description
latest master-branch (edit: dev-branch)
stable last version label (now: v0.0.1, next week: v0.0.2)
v.0.0.1, v0.0.2, .... all versions we do release
dev dev-branch
master master-branch

storage_invest example does not work for a fixed storage

If you switch the investment option to False the example raises an error.

- transformer.Storage.optimization_options.update({'investment': True})
+ transformer.Storage.optimization_options.update({'investment': False})

storage = transformer.Storage(uid='sto_simple',
                              inputs=[bel],
                              outputs=[bel],
                              eta_in=1,
                              eta_out=0.8,
                              cap_loss=0.00,
                              opex_fix=35,
                              opex_var=10e10,
                              capex=1000,
-                             cap_max=0,
+                             cap_max=1000,
                              cap_initial=0,
                              c_rate_in=1/6,
                              c_rate_out=1/6)
Traceback (most recent call last):
  File "/home/uwe/rli-lokal/git_home/oemof_base/examples/storage_optimization/storage_invest.py", line 155, in <module>
    energysystem.optimize()
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/core/energy_system.py", line 89, in optimize
    self.optimization_model = OM(energysystem=self)
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/optimization_model.py", line 114, in __init__
    assembler.registry[cls](e=None, om=self, block=block)
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/optimization_model.py", line 551, in _
    om.default_assembler(block)
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/optimization_model.py", line 162, in default_assembler
    block.optimization_options[option](self, block)
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/optimization_model.py", line 532, in linear_constraints
    var.set_bounds(om, block, side='output')
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/variables.py", line 144, in set_bounds
    model.w[e1, e2, t].setub(out_max[e1][0])
TypeError: 'NoneType' object is not subscriptable

Find a way for string representation of 'blocks' inside solph

At the moment solph uses blocks for every base class to group constraints and variables etc. Blocks are
attributes of the OptimizationModel() instance. Names of the attributes are set with the class name converted to a string.

This is very unhandy for debugging and model analysis (e.g. lp-files) and for calling these attributes as well as they can only be called with getattr(model, str(class)).

We should find a way to have a simple, stringent and short string representation for the blocks.

Delete an orphan Bus

I created a lignite resource bus by hand but there is no lignite power plant in my region.

So I check all buses and want to delete the orphan ones. The following doesn't work:

buses = [obj for obj in MyEnergySystem.entities if isinstance(obj, Bus)]
for bus in buses:
    if len(bus.inputs) > 0 or len(bus.outputs) > 0:
        logging.debug('Bus {0} has connections.'.format(bus.type))
    else:
        logging.debug('Bus {0} has no connections and will be deleted.'.format(
            bus.type))
        MyEnergySystem.entities.remove(bus)

I assigned it to @gnn but maybe anybody else has an idea (@cswh, @simonhilpert, @ckaldemeyer).

Revise docstrings

State of existing docstrings

(1) no docstring
(2) insufficient docstring, wrong layout
(3) sufficient docstring but wrong layout
(4) seems okay

core/energy_system.py

  • EnergySystem (1)
  • EnergyRegion (1)
  • Simulation (1)

core/network/init.py

  • Entity (2)

core/network/entity/init.py

  • Bus (2)
  • Components (3)

core/network/entity/components/init.py

  • Sink (2)
  • Source (2)
  • Transformer (3)
  • Transport (2)

core/network/entity/components/source.py

  • FixedSource (2)
  • DispatchSource (2):
  • Commodity (2)

demandlib/demand.py

  • electrical_demand (5)
  • methods of electrical_demand (1-3)

Check, revise and ask for support if necessary.

Allow entities to have non string uids

Using the Two-Region-Example with the actual commit (e87fd93) on the two_region_example branch, I get a pyomo-error. I do not know pyomo very good but I checked the entities and could not find anything. Everything seems to be like it was before.

Does anybody has an idea what cases this error?

INFO:root:Processing region: Landkreis Wittenberg (LanWit)
INFO:root:Processing region: Stadt Dessau-Roßlau (StaDes)
ERROR: Constructing component 'w_index_0' from data=None failed:
    ValueError: The value=('bus', 'Landkreis Wittenberg', 'elec', 'sink', 'Landkreis Wittenberg', 'elec') does not have dimension=2, which is needed for set=w_index_0
ERROR:pyomo.core:Constructing component 'w_index_0' from data=None failed:
ValueError: The value=('bus', 'Landkreis Wittenberg', 'elec', 'sink', 'Landkreis Wittenberg', 'elec') does not have dimension=2, which is needed for set=w_index_0
Traceback (most recent call last):
  File "/home/uwe/rli-lokal/git_home/oemof_base/examples/development_examples/two_regions_example.py", line 259, in <module>
    TwoRegExample.optimize()
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/core/energy_system.py", line 89, in optimize
    self.optimization_model = OM(energysystem=self)
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/optimization_model.py", line 89, in __init__
    var.add_continuous(model=self, edges=self.all_edges)
  File "/home/uwe/rli-lokal/git_home/oemof_base/oemof/solph/variables.py", line 79, in add_continuous
    model.w = po.Var(edges, model.timesteps, within=po.NonNegativeReals)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/block.py", line 448, in __setattr__
    self.add_component(name, val)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/block.py", line 686, in add_component
    self._add_temporary_set(val)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/block.py", line 593, in _add_temporary_set
    val.cname()+"_index_"+str(ctr)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/block.py", line 620, in _construct_temporary_set
    self.add_component(name,obj)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/block.py", line 780, in add_component
    val.construct(data)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/sets.py", line 1197, in construct
    self.add(val)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/sets.py", line 746, in add
    self._verify(tmp)
  File "/usr/local/lib/python3.4/dist-packages/pyomo/core/base/sets.py", line 699, in _verify
    raise ValueError("The value="+str(element)+" does not have dimension="+str(self.dimen)+", which is needed for set="+self.cname(True))
ValueError: The value=('bus', 'Landkreis Wittenberg', 'elec', 'sink', 'Landkreis Wittenberg', 'elec') does not have dimension=2, which is needed for set=w_index_0

Renaming the code folder of oemof_base to avoid errors

@oemof/oemof-main : Shall we just rename the code folder to oemof_base?

The python convention is to name the code folder as the package name. @gnn said that it should also work with different named folders but right now it causes errors (see #44).

As long as nobody knows how to avoid these errors I vote for renaming the code folder to oemof_base.

I label it urgent because at the moment the example does not work if you install oemof using
pip3 install oemof_base.

How to connect a power plant to an existing bus

Example: Natural gas power plant

To define the simple transformer, i have to pass the bus objects. So I have to find them in the list of entities of the energy system. As far as I understood oemof, all entities are automatically written to the list of entities in the object of the EnergySystem class.

As you suggested I am using tuples to identify the entities.

# Creating the energy system
ExampleSystem = es.EnergySystem()

# Creating regions
ExampleSystem.regions.append(es.Region(geom=GeoObj1, name=region1))
ExampleSystem.regions.append(es.Region(geom=GeoObj2, name=region2))

# Creating a global gas bus
Bus(uid=('bus', 'global', 'ngas') , type='ngas', price=60, sum_out_limit=10e10)

for region in list_of_regions
    # Creating a electricity bus for each region.
    Bus(uid=('bus', region.name, 'elec') , type='electricity', price=60, sum_out_limit=10e10, regions=[region])

    # Creating a gas power plant for each region
    transformer.Simple(
            uid=('ngas_power_plant', 'region.name', 'ngas', 'elec'),
            inputs=ExampleSystem.entities[??????],  # Global gas bus
            outputs=ExampleSystem.entities[??????],  # Local electricity bus
            in_max={('bus', 'global', 'elec'): None},
            out_max={('bus', region.name, 'elec'): 10000},
            eta=[0.4])

Unique class names

At the moment I am working on a dataframe representation of the new result object which enables statistics, plotting ,etc..

While extracting the data from the result dictionary I used the class names to figure out what kind of object I am dealing with and also to use the class name as pandas index. If I use Pythons built in object.class.name this delivers the class of the object e. g. Bus or SimpleExtractionCHP. Since the classes Transport, Transformer and Sink all have a common subclass Simple the usage of delivers ambiguous object.class.name results.

Having unique core class names might be handy in some cases where objects are treated by there type. In my case it helps me to create "speaking names" since some object-uids in renpass-gis are not speaking for themselves. And I still remember Simon introducing a core class attribute "lower_name" to treat classes which is now also solved by using type(object).

My point: I think having unique class names could be handy for current and future applications

@oemof/oemof-main: What do you think?

Cheers
Cord

Check implementation of time-increment indepency

So far we are only calculating on an hourly basis which implies that power and energy have the same value e. g. 1 MW equals 1 MWh. This is also reflected in all underlying solph-equations which to not distinguish between power and energy.

To allow time-increment independency, all equations that contain energy balances have to be extended by a multiplication with the time-increment.

Example:

A (very) simple storage balance:

W_sto(t)= W_sto(t-1) + Tau * (P_sto_in(t) - P_sto_out(t)) for all t element [1, t_max]

In this case "Tau" is the chosen time-increment (e.g. 0.25 h).

Abstract Base Class Attributes

We already had some discussions about the attributes and their meaning of the base-class objects.

At the moment we are using a mix of well known economic notations such as opex, capex etc.
and technical parameters that refer to the graph nature of out energysystem model (in_max, out_max, etc)

I talked to @gnn and @ckaldemeyer and if I got it right, it might be a good idea to have abstractly named attributes to be consitent with the general representation as a graph.

Starting with an example:
Replacing the attributes:

self.in_max = ..
self.out_max = ... 
self.in_min = ... 
self.out_min = .. 
self.add_out_limit = .. 

by bounds::

self.bounds = kwargs.get('bounds',
                                     {'inflow': [None, (None, None), None],
                                      'outflow': [None, (None, None), None]}

Additionally for economic parameters:

 self.costs = kwargs.get('costs', {'inflow':  None,
                                          'outflow': 0,
                                          'ramping': {'up': None,
                                                           'down': None},
                                          'startup': None,
                                          'shutdown': None,
                                          'capital': None,
                                          'fix' : 0,
                                          'wacc': 0.05})

With such a (or a similar) structure we could allow for very individuell modeling of the energysystems
without having a huge amount of different attributes. I think in a mid-term perpective we should
move in this direction, maybe it is a good idea to do so before all apps etc. are finished?

What do you think: @gnn @ckaldemeyer @uvchik @cswh @caro-rli ?

Validation of results using tests

Within the development-phase of renpass-gis, results have to be validated. Since this is a general procedure for most models, the idea was to implement this using tests. If suitable, these tests can then be implemented into oemof_base afterwards.

Here are some quick ideas to start with (any further suggestions are welcome):

  • Bus balances: check if zero for all timesteps (regarding a small deviation "epsilon")
  • Transformers
    • Check if outputs divided through their efficiency equal their input for all timesteps
    • Check if full load hours are between 0 and 8760
  • Storages
    • Check storage balance over time (sum(inflow)>sum(outflow))
    • Check if SOC(t=0) is SOC(t=t_max)
  • Merit-Order-Checks
    • Check if order sort(marginal_prices) equals order of sort(full load hours)
    • Merit-Order plots (price vs. quantity): Check if all transformers on the right side of the required quantity (demand) are zero

@oemof/oemof-main : To you have any suggestions where to implement this? Using nose directly in the test folder?

@simonhilpert : Did I forget something?
@uvchik : I remember you telling me that you already had testing procedures at the RLI. Feel free to contribute!

Github issue filter for mentions group

Does anyone know how to filter the issues to show all issues where a group is mentioned?

  • mentions:cswh works
  • mentions:oemof/oemof-main does not work
    The function would make it much easier in my opinion to filter for relevant issues which need "urgent attention". If it does not work, we should have some better rules for the use of labels. So far there are no rules for labelling issues and everybody does it as he feels like?

sudo pip3 install oemof, import oemof not working

Tried to install oemof with "sudo pip3 install oemof". Everything seems to work fine, no errors, but import oemof in python got me a "no module named oemof" error. Downloading the zipped package and installing with "pip3 -e /path" worked fine, import oemof also. Do I have to adjust some environment variables when installing otherwise?

Coding & Documentation: American or British English?

As Caro mentioned, another decision has to be made about the spelling. This is quite fundemental and should be written down in the documentation part "How to document?".

I vote for British English since we are mostly located in and focused on Europe and the openmod-initiative already also uses British English.

Add mathematical descriptions/notations for solph

The mathematical description in solph is not 100 % in line. For this a static rst. file should be created. This file will contain general informations and notations for the mathematical description.

The following infos should be given in a structured(table-like) format:

variable names,
math. sets,
math. parameter

Docstrings in solph should be in line with these general informations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.