Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make varying period lenghts possible #957

Merged
merged 26 commits into from
Aug 10, 2023

Conversation

nailend
Copy link
Contributor

@nailend nailend commented Jul 19, 2023

Changes

This feature fixes #955 and introduces the capability to utilize multi-periods with varying lengths. To achieve this, the _old_capacity_rule_end in the investment_flow_block and _old_storage_capacity_rule_end of generic_storage were reworked. It seems that the same approach needs to be applied to SinkDSM as well.

Challenges

The methodology behind this implementation can be quite complex to grasp. I have attempted to provide as many comments as possible to aid understanding. The major challenges encountered were as follows:

  1. Matching investment periods with decommissioning periods.
  2. Incorporating periods without decommissioning.
  3. Accounting for periods with decommissioning of multiple investment periods. (That's the reason for the complicated for loop)

Description

The method is based on an upper-right matrix that describes the temporal distance between each of the periods. Let's consider an example with the following periods:

  • 2000, 2020, 2035, 2045, 2050, 2060, 2075, 2095
  • component lifetime of 20 years.

The period matrix appears as follows:

periods_matrix

In this matrix, the values represent the age of a component based on the period it was invested in (rows) and decommissioned (columns). The value at the top-right corner indicates that a component would be 95 years old if it was invested in period 0 and decommissioned in period 7.

To match investment periods with decommissioning periods, we need to select, for each row, the smallest value that is greater than or equal to 20 (the lifetime). We then obtain the respective indexes, where the row index corresponds to the investment period and the column index corresponds to the decommissioning period.

periods_matrix_2

Additionally, it is necessary to address periods without decommissioning (depicted in blue boxes) and periods where multiple investment periods are decommissioned (depicted in green boxes).

periods_matrix_3

Remarks

It's probably possible to do this without this complicated for-loop but I did't find a solution to group duplicated investment periods to chain and add them to the constraint.

Help

I guess the LP-file test should be sufficient. Please double-check the logic for c_e_GenericInvestmentStorageBlock_old_rule_end and c_e_InvestmentFlowBlock_old_rule_end.

  • Do you think there is anything else missing?
  • Is there anything to do in the documentation?

Thanks for your help

TODO:

  • implement in investment_flow_block
  • implement in generic_storage
  • implement in SinkDSM
  • add SinkDSM to LP-file test
  • add test
  • remove same test
  • add LP-file test
  • reduce timesteps of LP-test

This matrix represent the temporal distance between each period point
to each other. It is necessary to determine the endogenous decommissioning
with the multi-period approach.
This is necessary to fix a bug when using multi-period with varying
period lengths. Now various period lengths are possible and even
multiple investment periods can decomission in one period.
This changes are similiar to _old_capacity_rule_end but indexes for constraints
are different. This constraint takes care of the storage capacity (MWh).
@nailend nailend self-assigned this Jul 19, 2023
Copy link
Member

@jokochems jokochems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @nailend! This looks sound to me. Congrats to coming up with a well-thought thorugh, though quite complicated fix for that. I guess the reason for having a rather complicated fix is that the issue itself brings that complication, right? ;-)

I suggested some minor code modifications, but would not alter the essence of it. Also, I think, we need to remove all that inline commenting and document it somewhere central. I guess, I'd rather prefer having a dedicated section on that in the sphinx documentation, compared to blowing up the docstrings for that constraint formulation, but we can argue about that.

src/oemof/solph/_energy_system.py Outdated Show resolved Hide resolved
src/oemof/solph/components/_generic_storage.py Outdated Show resolved Hide resolved
@jokochems
Copy link
Member

jokochems commented Jul 20, 2023

It seems that the same approach needs to be applied to SinkDSM as well.

You're correct about that. It is basically the same as for any investment flow. We might address these code "duplications" at some point in the future, but that's another issue.

Also you might look into the open black issues.

@jokochems
Copy link
Member

Is there anything to do in the documentation?

Concerning that, my preference would be to have a dedicated subsection under the multi-period mode in the usage.rst file as well as a an extended docstring for that altered constraint rules. The current inline commenting should be reduced to a minimum.

@nailend
Copy link
Contributor Author

nailend commented Jul 20, 2023

@jokochems Thanks a lot for your review. I took care of the modifications you suggested and a few other things like the constraint test.

I tried to reduce the inline comments, but as you said yourself, it is quite complex, even if you are the person who knows best about it. To make the code understandable and open to changes by developers, I would prefer to keep them. Whereas, I don't think this level of detail is necessary for the user, so I just added a few words to the usage.rst.

Would you like to double-check the LP-file again, or do you think it's ready to merge? (To check the constraints ending with _rule_end is enough and luckily quite easy with the matrix from above)

Thanks again for your support.

@nailend nailend requested a review from jokochems July 24, 2023 11:32
Copy link
Member

@jokochems jokochems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not work through each and every detail again. It's pretty much the same approach for each component that is eligible for investments, right?

I suggest to alter the wording to "bookkeeping" instead of "memory".

In terms of the inline comments, I'd be fine with it, but I'd like to hear @p-snft's take on that and would like to leave a final review and approval up to him.

docs/usage.rst Show resolved Hide resolved
src/oemof/solph/components/_generic_storage.py Outdated Show resolved Hide resolved
@jokochems jokochems requested a review from p-snft July 28, 2023 15:17
Copy link
Member

@jokochems jokochems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had another look into the decailts: To me it looks all good and I understand the logics as well as the analogies (you might say duplications) that are there.

The minor remarks on the wording hold for all code occurences, i.e. _generic_storage.py, _sink_dsm.py as well as _investment_flow_block.py.

One thing that was a bit counter-intuitive is that in the constraint test, the setup method gets somewhat "overwritten" as an energy system is set up twice (you'll notice when debugging and putting a break point into the new _extract_periods_matrix method). But I'd say, that's also okay, because this is an experts user area anyways and the test does what it is supposed to do and succeeds.

src/oemof/solph/components/_generic_storage.py Outdated Show resolved Hide resolved
@nailend
Copy link
Contributor Author

nailend commented Jul 31, 2023

Thanks a lot!

One thing that was a bit counter-intuitive is that in the constraint test, the setup method gets somewhat "overwritten" as an energy system is set up twice.

Yes, this is done by purpose as the setup method only has three periods defined and there were more needed to check the various decommissioning cases.

@p-snft p-snft force-pushed the features/make-varying-period-lenghts-possible branch from 5acd141 to 889a81a Compare August 10, 2023 18:10
Copy link
Member

@p-snft p-snft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely an improvement. It might not be optimal, but as we still have the disclaimer for multi-period optimisation

CAUTION! (…) Please be aware that the feature is experimental as of now.

I am very okay with that. For the future, we should talk about refactoring the tests, so that understanding the tests is easier. (I did not go through the lengthy LP files.) But that's a general issue with solph and not specific to the current PR.

@p-snft p-snft merged commit 3006fa7 into dev Aug 10, 2023
11 checks passed
@p-snft p-snft deleted the features/make-varying-period-lenghts-possible branch August 10, 2023 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Determining commission period fails if multi-periods don't have the same length
3 participants