oemof / demandlib

Creating heat and power demand profiles from annual values.
https://oemof.org
MIT License
54 stars 38 forks source link

Possibility to define seasons #38

Closed smartie2076 closed 2 years ago

smartie2076 commented 3 years ago

Hi @all,

@theoneandra and I want to use the demandlib for estimating a demand profile in South America. Of course, for that we would have to tweak the profile in a way that their actual seasons are taken into account. We found something about seasons in the docstrings and a part of the code here:

https://github.com/oemof/demandlib/blob/7371f386236dfbf7b1ba9868b30d28291793b6ef/demandlib/bdew/elec_slp.py#L22

https://github.com/oemof/demandlib/blob/7371f386236dfbf7b1ba9868b30d28291793b6ef/demandlib/bdew/elec_slp.py#L39

https://github.com/oemof/demandlib/blob/7371f386236dfbf7b1ba9868b30d28291793b6ef/demandlib/bdew/elec_slp.py#L54

However the function does not work and, indeed, there is no utilization of self.seasons anywhere else. Is this old code that should be deleted, or is this still in progress somewhere?

TheOneAndra commented 3 years ago

While experimenting the demandlib and seasonality parameter I noticed something:

It seems like the seasons dictionary I created (adapted to south americas's seasons) works and has an effect on the demand profile as the highest demand is now during the European winter (see example below)

image

But I also noticed that if the dynamic function is set to True and I simulate a household (h0) profile, the dynamic function takes over my seasons dictionary. This results in a nice curve but with peak demand during European winter (see picture below).

image

uvchik commented 3 years ago

You should keep in mind that the profiles are based on statistical data of the electricity usage in Germany. You may have a statistical and systematic deviation.

If you decided that the German situation is suitable for South America you should have a look at this code. It is an empirical function that has the seasons included (see below).

I think we should remove the season parameter as it does not work for the h0_dynamic profile.

If we would add a parameter such as southern_hemisphere=True we would imply that the data is valid for other countries but it is not :exclamation: You may decide that the approach is suitable for other countries and you might be able to give reasons but than you have to shift the results for example using numpy.roll and resetting the index.

grafik

smartie2076 commented 3 years ago

Thank you for the feedback @uvchik!

If you decided that the German situation is suitable for South America you should have a look at this code. It is an empirical function that has the seasons included (see below).

Oh, interesting! This is good to know for the future. We actually have the monthly demands, so in theory we would be create a function like that from it.

If we would add a parameter such as southern_hemisphere=True we would imply that the data is valid for other countries but it is not ❗ You may decide that the approach is suitable for other countries and you might be able to give reasons but than you have to shift the results for example using numpy.roll and resetting the index.

Yeah, I agree, this might induce false confidence in the demandlib results for other countries. I do think, however, that demandlib is nice to use for a very first estimation of the profile (if the contractors do not provide any data) - maybe documenting this in the RTD of the demandlib would be good?

Numpy.roll is also a good alternative approach, but would not take into account the duration of the seasons... but then allow a dynamic shape 🤔

I do not think we will put more work into the demand profile at this stage, but we will remember this next time around.

uvchik commented 2 years ago

I just add some information if anybody will stumble over this problem:

It is possible to change the seasons and create load profiles. The profile h0_dyn is not valid for changed seasons.

The used smoothing function is empirical and looks like this:

As a workaround one can create an adapted smoothing function.

slp = bdew.ElecSlp(year, seasons=alternative_seasons)

h0 = slp.get_profiles("h0")

# Get the day of the year as a decimal number
decimal_day = pd.Series(
    [((q + 1) / (24 * 4)) for q in range(len(h0))],
    index=h0.index,
)

# Calculate the smoothing factor of the dynamic H0 profile
# You have to exchange the factors by your adapted factors
smoothing_factor = (
    -3.916649251 * 10 ** -10 * decimal_day ** 4
    + 3.2 * 10 ** -7 * decimal_day ** 3
    - 7.02 * 10 ** -5 * decimal_day ** 2
    + 0.0021 * decimal_day
    + 1.24
)

# Multiply the smoothing factor with the default H0 profile
h0_dyn = h0.mul(smoothing_factor, axis=0)