TulipaEnergyModel.jl icon indicating copy to clipboard operation
TulipaEnergyModel.jl copied to clipboard

Multi-year investment

Open datejada opened this issue 1 year ago • 16 comments

Description

Update the model to handle multi-year investments. The checks below should be converted into issues when this development starts, to keep the changes as atomic as possible.

One big challenge in this implementation is the data handling. For instance, the capacity of the assets will be year-dependent, meaning that they will no longer be a single value, but a vector or time series. Therefore we will have a large data set for the input data.

Must-haves and nice-to-haves

For this epic, we want a working version that achieves the same features as COMPETES and allows different levels of detail for performance considerations. This means we want the following.

  • [x] The main temporal structure would be milestone years for both investment and operation.
  • [x] Simple weights for the in-between years.
  • [x] Economic representation
  • [x] Use total cost for Capex calculation.
  • [x] Decommissioning for existing and new capacities (note: we allow inputs for existing capacities in the forms of both individual plants and aggregated capacities, as we have for COMPETES)

This leaves us the following nice-to-haves.

  • Complex temporal structures such as milestone years for investment, and more years for operation
  • Complex weights for the in-between years such as the mapping matrix.
  • ~Add annualized cost for Capex calculation.~ (done in #810 #826)
  • Mothballing, retrofitting.
  • ~[Can be a new epic] A new "entity" called "group" to have a set of common constraints, such as investment potential for a group of assets (e.g., different wind techs a total potential in the NL)~(done in #732). Also, use methods such that one can have a common investment variable (if only the efficiencies are different).

Sub issues

  • [x] #690 which covers all the must-have features
  • [x] #732
  • [x] #745
  • [x] #766
    • Separate static data and non-static/yearly data.
    • Differentiate milestone years and non-milestone years. We need to put some information on whether this is a milestone year (that we can invest) or this is a year for the vintage/existing capacities. Names can be discussed.
  • [x] #765
  • [x] #777
  • [x] #778
  • Different levels of detail
    • [x] ~#722~ (in favor of #786 )
    • [x] ~#740~ (after discussion, we will drop this)
    • [x] #783
    • [x] #786
    • [x] #792
    • [x] #806
  • [x] ~Add existing capacity, and create/modify the needed parameters~ (will be done within different levels of detail)
  • [x] ~Add decommissioning in the model, and create the needed parameters~ (will be done within different levels of detail)
  • [x] #797
  • [x] #798
  • [x] #790
  • [x] #791
  • [x] #789
  • [x] #838
  • [x] #802
  • Add economic parameters
    • [x] #810
    • [x] #816

Improvements

  • [x] #831
  • [x] #825: also update objective value in the test
  • [x] #826
  • [x] #835

After first release

  • [ ] #819
  • [ ] Update documentation - how-to; Also add this table https://github.com/TulipaEnergy/TulipaEnergyModel.jl/issues/462#issuecomment-2345997142

In the refactor (mainly related to performance improvements)

  • [ ] #818 (see complication in this issue)
  • [ ] #828
  • [ ] Set the domain of decommission variables such that they only exist when there are existing capacities or investments - simple method
  • [ ] Avoid creating vintage variables when they do not have a different profile.

datejada avatar Feb 12 '24 14:02 datejada

This will influence #505. We should have a brief discussion about where years come up, and how they propagate. Are they present in the profiles from the influxDB?

abelsiqueira avatar Feb 29 '24 09:02 abelsiqueira

We discussed some data aspects of this issue on 15/04/2024:

  • We want to use time series (as in profiles) for some (all?) year "static" data. E.g., cost for 2040 and 2050 of an asset.
  • We want to use profile names to indicate the profiles of specific weather scenarios/years, as we are doing now for a single year. Currently we define the profile of an "asset" by saying its "type" and "name", which is enough to uniquely identify a loaded profile. In the future, we could define the profile of an "asset" in a specific "year" by saying its "type" and "name", with the same result.
  • We want a user interface, or helper functions at least, to help declare these profile definitions. For instance, to say that the profile of an asset is always equals to its 2015 version, except for 2020. This should probably be matched with the #414 interface.

abelsiqueira avatar Apr 15 '24 14:04 abelsiqueira

We discussed how to move forward on 02/09/2024 with @abelsiqueira @datejada @g-moralesespana

Note: when I talk about data input, I mean data input for the TEM, e.g., assets_data.csv. The raw data should already be processed somehow outside TEM.

  • We will only support two method: simple and compact. Doing vintage through data for the simple method is possible but requires a different data input. We will not support the creation of this data input. This would most probably only be need a few times and the data should be created manually.

  • For the two methods, we will only use one data input, that is the data with the most detailed information we need, i.e., for the compact one. We would need different parameter for the initial capacity for the two methods, i.e., $p^{\text{init capacity compact}}_{y, v}$ indicating the initial capacity from investment year $v$ operating at year $y$ and $p^{\text{init capacity simple}}_y$ indicating the initial capacity operating at year $y$.

    • For the compact method, $p^{\text{init capacity compact}}_{y, v}$ will be taken directly from the data. For the simple method, $p^{\text{init capacity simple}}_y$ will be calculated in TEM by summing up the other parameter.
  • Each types of asset can have a method.

    • If you don't choose a method, it means doing what TEM does now, e.g., for the transport asset.
    • The method for the type of asset should be static data, i.e., it does not change over years.
  • After merging #745, we will do 3 things before we move on the implement the methods (I will also move the below action points to the main post).

    • Separate static data and non-static/yearly data.
    • Differentiate milestone years and non-milestone years. We need to put some information on whether this is a milestone year (that we can invest) or this is a year for the vintage/existing capacities. Names can be discussed.
    • Create a test dataset for multi-year that makes more sense, considering existing capacities with different profiles.

gnawin avatar Sep 02 '24 14:09 gnawin

@g-moralesespana, the ramping constraints also must be modified to consider the accumulated investment (either simple or compact) in the constraints' RHS. Am I correct?

EDIT: And the constraints for the charging and discharging limits for storage assets when adding the binary variable to avoid simultaneous charging and discharging

datejada avatar Sep 11 '24 10:09 datejada

Yes that is correct. The ramp is in unit of installed capacity. It is like in the clustered unit commitment, the ramp gets scaled by the number of units on, and the upper bound of the number of units on is given by the number of invested units. Similar with the storage also...

g-moralesespana avatar Sep 11 '24 10:09 g-moralesespana

@gnawin can an asset have a missing investment_method? Or must we guarantee in the input data that we always use either simple or compact?

If we allow investment_method==missing what does that mean in the constraints?

My opinion: It can't be missing, but I am open to listening to other options

datejada avatar Sep 11 '24 10:09 datejada

@g-moralesespana and @gnawin, we need to add something for the investment in the flows; otherwise, the model could invest one year to get capacity, and the next one doesn't invest, and the capacity disappears; that is weird. I suggest we implement the same equations for the simple method to flow for the time being. Then, we will have the lifetime parameter to avoid that situation. What do you both think?

datejada avatar Sep 11 '24 12:09 datejada

What you mention flows, you mean to have investment in lines/connections, right? Yes, we can use the simple method, which includes lifetime.

g-moralesespana avatar Sep 11 '24 12:09 g-moralesespana

@datejada I agree that we should not allow investment method to be missing. And as @g-moralesespana mentioned, investment in flows should use the simple method.

What I was hesitant about is hub and consumer, that's why I removed that from the data, do we have a capacity constraint there?

gnawin avatar Sep 12 '24 07:09 gnawin

@datejada I agree that we should not allow investment method to be missing. And as @g-moralesespana mentioned, investment in flows should use the simple method.

What I was hesitant about is hub and consumer, that's why I removed that from the data, do we have a capacity constraint there?

Great. It is better to have all defined even if they don't yet have a capacity constraint. My question was also because in the multi-year case study, the ens is a producer with an empty method. But I will fix it in the input data and in the structure.

Thanks both!

datejada avatar Sep 12 '24 07:09 datejada

After discussion with the team, we need the following options:

investment_method investable investment variable decommission variable
none TRUE FALSE FALSE
none FALSE FALSE FALSE
simple TRUE TRUE TRUE
simple FALSE FALSE TRUE
compact TRUE TRUE TRUE
compact FALSE FALSE TRUE

datejada avatar Sep 12 '24 11:09 datejada

@gnawin I suggest having this table (or similar) in the update of the documentation: https://github.com/TulipaEnergy/TulipaEnergyModel.jl/issues/462#issuecomment-2345997142

datejada avatar Sep 13 '24 06:09 datejada

@gnawin With the proposed formulation, the concept of initial_units has changed since it depends on the year. As it is now, that parameter is actually representing the existing_units at that year. Note that the formulation does not accumulate that parameter over the years, so if the data is initial_units[2030] = 1 and then initial_units[2050] = 0, then the constraint for 2050 won't count the "initial" (I would say existing) units in 2030, it would assume that they were "decommissioned" for free.

It will depend on what we want to represent and how. Some options that I see:

  • Keep initial units, but then make it not year-dependent
  • Change the parameter to existing units and keep the year dependency. But, here there are two options:
    • Don't accumulate it in the constraint: then, the user needs to consider that any increase/decrease in this value will be investments/decommissions for free that year, like the example I showed before.
    • Accumulate the values: This is similar, but here, if initial_units[2030] = 1 and initial_units[2050] = 0, the constraint in 2050 will still consider the units in 2030 because they are accumulated.

As I said, it is a matter of what we want to represent and how.

I prefer the option of making the initial_units not year-dependant. But please discuss it with German.

@g-moralesespana, any thoughts on this?

datejada avatar Sep 13 '24 06:09 datejada

@gnawin since we are working with the accumulated units, then either the capacity should not depend on the year or if it depends on the year then it should be multiplying the units in the accumulated expression and then represent the accumulated capacity instead of the accumulated units.

As it is formulated, if the user has capacity[2030] = 100MW and capacity[2050] = 200MW, you will get for free extra 100MW for each unit invested in 2030 when you analyze the 2050. Do you see what I mean?

Again, it depends on what we want to represent and how. So, if the capacity is not dependent on the year, we don't need to change the expression of the current accumulated units. If we want to keep the capacity changing by year, we must change the accumulated expression to represent the accumulated capacity instead of the accumulated units.

Here, I prefer capacity non depending on the year...

@g-moralesespana, any thoughts?

datejada avatar Sep 13 '24 07:09 datejada

@gnawin since we are working with the accumulated units, then either the capacity should not depend on the year or if it depends on the year then it should be multiplying the units in the accumulated expression and then represent the accumulated capacity instead of the accumulated units.

As it is formulated, if the user has capacity[2030] = 100MW and capacity[2050] = 200MW, you will get for free extra 100MW for each unit invested in 2030 when you analyze the 2050. Do you see what I mean?

Again, it depends on what we want to represent and how. So, if the capacity is not dependent on the year, we don't need to change the expression of the current accumulated units. If we want to keep the capacity changing by year, we must change the accumulated expression to represent the accumulated capacity instead of the accumulated units.

Here, I prefer capacity non depending on the year...

@g-moralesespana, any thoughts?

@datejada Yes, I agree. I realized that because I was in a rush to translate the formulation into Tulipa jargons before sending the pdf to you, I made some mistakes regarding this. The idea behind the formulation was indeed a capacity NOT depending on year...but we can discuss further

gnawin avatar Sep 13 '24 08:09 gnawin

I suppose all this was already solved in our last meeting.

g-moralesespana avatar Sep 17 '24 11:09 g-moralesespana