rl-institut / multi-vector-simulator

Multi-vector Simulation Tool assessing and optimizing Local Energy Systems (LES) for the E-LAND project
GNU General Public License v2.0
21 stars 10 forks source link

Maximal cap adapted with timeseries peak #962

Open Bachibouzouk opened 1 year ago

Bachibouzouk commented 1 year ago

In open-plan-tool we noticed a peculiar behavior of MVS.

For a simple setup with a PV plant, a DSO and a demand (plus a bus). The DSO energy price is set very high and the feedin tariff as well so that it is profitable to invest in PV up to its maximum capacity.

The result is that the optimized cap is NOT the maximum capacity, rather it is depending on the input timeseries of the PV plant.

I noticed that in E1_process results module, the optimized capacity was divided by the timeseries peak: https://github.com/rl-institut/multi-vector-simulator/blob/18bec98ef405d4ba0097b5188ffbb5e375ef6271/src/multi_vector_simulator/E1_process_results.py#L655

Is there a specific reason for this @smartie2076 @SabineHaas ? Did you remember why it was decided to do so?

smartie2076 commented 1 year ago

Hi @Bachibouzouk! Yeah, I remember: The oemof model does not behave well when the peak value of an asset that is to be optimized is below or above 1. Therefore, when adding the asset to the oemof model, it is normalized for optimization purposes: https://github.com/rl-institut/multi-vector-simulator/blob/18bec98ef405d4ba0097b5188ffbb5e375ef6271/src/multi_vector_simulator/D1_model_components.py#L987C5-L999C5 The determined capacity is then actually the normalized capacity and the line you found in E1_process_results fixes this.

smartie2076 commented 1 year ago

I was thinking maybe we did not normalize the maximum capacity as well - but we somehow did:

https://github.com/rl-institut/multi-vector-simulator/blob/18bec98ef405d4ba0097b5188ffbb5e375ef6271/src/multi_vector_simulator/D1_model_components.py#L979-L982

However, I am not 100% sure that this if-loop is correct, meaning if all timeseries that have a values out of [0,1] have an MAXIMUM_ADD_CAP_NORMALIZED. You could try to check this.

(You can check the other functions that add a non-dispatchable source to make sure).

Have you made sure your timeseries has no values below 0?

Bachibouzouk commented 1 year ago

Have you made sure your timeseries has no values below 0?

I made a test with constant values timeseries of 0.5 and 1.5 for test purposes

smartie2076 commented 1 year ago

Did you test for timeseries of 1?

smartie2076 commented 1 year ago

@Bachibouzouk what I tend to do in these situations is look at the LP file. The maximum capacity is defined explicitly there, as is the timeseries. So basically you can cross check with the actual LP file if the model was set up correctly. If it wasnt you know where to look (D1 or earlier) - and if it was you now that, too (E1 or later).

Bachibouzouk commented 1 year ago

I found out that the discrepancies between MVS and open_plan are due to results processing (open_plan now uses the direct output from oemof-solph and thus there is no rectification of the optimized_add_cap)

Bachibouzouk commented 1 year ago

@smartie2076 - if the optimized_add_cap fixed from normalized capacity by dividing by the timeseries peak value. Shouldn't the flow result also be fixed and divided by the timeseries peak value?

smartie2076 commented 1 year ago

I found out that the discrepancies between MVS and open_plan are due to results processing (open_plan now uses the direct output from oemof-solph and thus there is no rectification of the optimized_add_cap)

Ah, that makes sense.

if the optimized_add_cap fixed from normalized capacity by dividing by the timeseries peak value. Shouldn't the flow result also be fixed and divided by the timeseries peak value?

Oh, that is true! I havent thought about this, might be that we are not doing it. Meaning, this will also impact the RES factor and so on - a bug worth fixing.

Bachibouzouk commented 1 year ago

I did a few tried directly with oemof-solph and it seems to me that we should not alter the maximum_cap depending on the timeseries peak value prior to optimization, but rather modify the optimized flow (multiply by timeseries peak value)

Bachibouzouk commented 1 year ago

energy_system_graph

Those are notes to myself which are not redacted very well right now, apologizes

I used a simple structure with only a dso, a pv plant and a fix demand (set to one all the time)

I consider two cases

In an oemof-solph model by setting the pv with fix=0.5 for all timesteps (that is without normalizing the timeseries at all, in MVS this would be normalized into 1 for every timesteps and timeseries peak value of 0.5) and the maximum capacity to 50000.

With this I get in case (A) optimized_add_cap is 50000 which is the maximum I allowed and the flow is 25000 which correspond to optimized_add_cap fix and in case (B) optimized_add_cap of 2 and the flow is 1 which corresponds to optimized_add_cap fix

This make sense to me, now let's look how we should modify MVS to get the same results in this case:

Now if I provide fix = 1 for every timesteps (this is what MVS would do to a non-dispatchable source, take the timeseries and normalize it, in our case the timeseries is 0.5 at all timesteps, so normalized this becomes a timeseries with 1 at all timesteps)

I get in case (A) optimized_add_cap is 50000 which is the maximum I allowed and the flow is 50000 which is too high by a factor 2 and could be corrected by multiplying the flow by timeseries peak value and in case (B) optimized_add_cap of 1 and the flow is 1. In that case optimized add_cap is too low by a factor 2 but the flow is the same as in the simple oemof model

The fact that the correction to the results depends on case A or B is anoying because it is not the same variable which need to be adjusted in each cases. I guess then that the idea was to change the maximum as you mentionned @smartie2076.

Indeed, if one multiplies the maximum capacity by the timeseries peak (in that example 50000 * 0.5 = 25000) then we get in case (A) optimized_add_cap is 25000 which is the maximum I allowed and the flow is 25000 which is the expected value as in the simple oemof model and in case (B) optimized_add_cap of 1 and the flow is 1.

In both case optimized add_cap is too low by a factor 2 and this can be corrected for by dividing by the timeseries peak value.

Therefore @smartie2076, as this is the current implementation of the MVS there is no need to modify the optimized flows :)

smartie2076 commented 1 year ago

Hi @Bachibouzouk! Tried to follow your notes, but I think I am a bit confused.

In an oemof-solph model by setting the pv with fix=0.5 for all timesteps (that is without normalizing the timeseries at all, in MVS this would be normalized into 1 for every timesteps and timeseries peak value of 0.5) and the maximum capacity to 50000. With this I get in case (A) optimized_add_cap is 50000 which is the maximum I allowed and the flow is 25000 which correspond to optimized_add_cap * fix ...

This only makes sense to me, if you are only simulating one timestep or that you look at the flow in one timestep.

... in case (B) optimized_add_cap of 2 and the flow is 1 which corresponds to optimized_add_cap * fix

This actually only make sense to me if you are only simulating/looking at a single timestep. Because it should be demand == PV flow == 1, as the energy price from the DSO is higher then PV generation.

(btw: this does not prove that oemof-solph always manages well with non-normalized timeseries.)

This make sense to me, now let's look how we should modify MVS to get the same results in this case: Now if I provide fix = 1 for every timesteps

You changed both the model (oemof-solph to MVS) and the fix timeseries (0.5 to 1), so this is not straightforward below

I get in case (A) optimized_add_cap is 50000 which is the maximum I allowed and the flow is 50000 which is too high by a factor 2 and could be corrected by multiplying the flow by timeseries peak value...

Why is it incorrect? If you have a fix specific PV generation of 1 unit per timestep, then the generation in one timestep should be equal to the optimized_add_cap.

... and in case (B) optimized_add_cap of 1 and the flow is 1. In that case optimized add_cap is too low by a factor 2 but the flow is the same as in the simple oemof model

Same here, if your specific generation is 1, then optimized_add_cap should be 1 to supply a demand of 1.

The fact that the correction to the results depends on case A or B is anoying because it is not the same variable which need to be adjusted in each cases. I guess then that the idea was to change the maximum as you mentionned @smartie2076.

I do not follow.

Indeed, if one multiplies the maximum capacity by the timeseries peak (in that example 50000 * 0.5 = 25000) then we get in case (A) optimized_add_cap is 25000 which is the maximum I allowed and the flow is 25000 which is the expected value as in the simple oemof model and in case (B) optimized_add_cap of 1 and the flow is 1.

Above you said that you allowed a max cap of 50000.

In both case optimized add_cap is too low by a factor 2 and this can be corrected for by dividing by the timeseries peak value.

Therefore @smartie2076, as this is the current implementation of the MVS there is no need to modify the optimized flows :)

Okay glad to hear it, but I did not understand how you got there ;)

Bachibouzouk commented 1 year ago

This only makes sense to me, if you are only simulating one timestep or that you look at the flow in one timestep.

I used a timeseries of 3 steps where all steps have the same value for test purposes

Bachibouzouk commented 1 year ago

You changed both the model (oemof-solph to MVS) and the fix timeseries (0.5 to 1), so this is not straightforward below

I did not change the model, I still used a simple oemof-solph model, I just mimic MVS by giving for fix a timeseries with only 1 at all timesteps (I looked what value would be assigned to the fix argument of the source within MVS). However the input source timeseries remains 0.5 for all timesteps, so if the optimized add cap is 50000, then the flow should be 50000 * 0.5 = 25000, which is not the case if we just set fix =1 and a maximum of 50000

Bachibouzouk commented 1 year ago

As far as I understood, oemof-solph does not let the user provide a non-normalized timeseries for source fix parameter. In MVS we allow it and we perform the normalization for the user. In case (A) the flow would be too high as MVS oemof-solph model used a timeseries with 1 at every timesteps instead of 0.5 at everytimesteps. This is why MVS does the trick of multiplying the maximum by the timeseries peak and to divide the optimized_add_cap by the same factor

smartie2076 commented 1 year ago

Okay, then you confirmed the reason why we implemented the feature like this. 👍

@Bachibouzouk: Does that mean that you think that the weird PV capacities that you identified in the beginning of this thread

The result is that the optimized cap is NOT the maximum capacity, rather it is depending on the input timeseries of the PV plant.

originate from somewhere else? Any ideas?