Veda2.0 Released!


Early retirement for each year
#1
Dear VEDA community

Within a model coupling exercise, I receive the number of vehicle sales and vehicle scrappage on an annual level. While it works fine to implement the sales for each year via NCAP_PASTI, I am struggling with implementing the annual scrapping:

I tried to define the annual scrapping via RCAP_BND for each year (e.g. 2028, 2029, 2030, 2031, and 2032). With RCAP_BND(2028), I intend to define how many cars must be scrapped in the year 2028 without wanting to specify the vintage-year of the cars that have to be scrapped. After my model gave a matrix error (see at the bottom), I had a closer look into the documentation. 

If I understand it correctly, RCAP_BND can only be defined for a milestone year of a period (in my case: 2030) and the defined value is the "same bound for all vintages" (Source: documentation, Table with user input parameters in TIMES). So, what my model seems to do is that it wants to apply the RCAP_BND defined for 2030 separately for the cars with vintage 2028, 2029, etc. but this is not want I want. What I want is that the scrappage value in 2030 is applied for cars with all vintages together.


Is there a possibility to model the scrappage in the way I intend, i.e. defining for each single year how many cars are scrapped in total from all previous years together?

Alternatively, I was wondering if the SCAP_BND might provide a workaround solution for my problem: If I understand SCAP_BND correctly, it represents the total amount of capacity that has been retired in and before the period for which I define SCAP_BND for the milestoneyear (e.g., I define SCAP_BND for the milestoneyear 2030 with a value that contains the sum of all cars being scrapped until 2036, which is the last year that belongs to the period of the 2030 milestoneyear). With this I would not be able to define the scrapping on an annual level, but at least I can tell the model how many cars are scrapped is total within and before each period. Thus, I could sum-up the scrappage from all years within the period plus all years before the period (which I get from the external model) and feed this to TIMES with SCAP_BND for the respective milestone year. Is my understanding of how I could use the SCAP_BND in my situation correct?
Kind regards,
Sandro

Matrix error from initial trial:
Lower bound > upper bound, because:
  • Lower bound = RCAP_BND defined for milestoneyear 2030

  • Upper bound = NCAP_PASTI defined for vintage year 2028


These are the error messages from the .lst-file:
[...]
*** Matrix error - lower bound > upper bound
VAR_SCAP(CH,2024,2030,T_C-ICE-GSL_BHIO-S3)   (.LO, .L, .UP = 0.004134, 0, 0.001508)
**** Matrix error - lower bound > upper bound
VAR_SCAP(CH,2024,2030,T_C-ICE-GSL_BHIO-S4)   (.LO, .L, .UP = 0.002829, 0, 0.000337)
**** Matrix error - lower bound > upper bound
VAR_SCAP(CH,2024,2030,T_C-ICE-GSL_BLIO-S1)   (.LO, .L, .UP = 0.000247, 0, 0.000232)
[...]
Reply
#2
> Is there a possibility to model the scrappage in the way I intend, i.e. defining for each single year how many cars are scrapped in total from all previous years together?

An exogenous "scrapping" profile by vehicle age can be defined by using NCAP_CPX(r,v,p) with a SHAPE index.
For some earlier discussion, see: New vehicles retirement
But there is no way to define for each single year how many cars must be retired in total from all previous years, unless you would use single-year periods, simply because there are no variables in the model for each single year, unless the periods are single-year periods. Moreover, it is not even clear to me what exactly you mean by "in total from all previous years".

> Is my understanding of how I could use the SCAP_BND in my situation correct?

As far as I know, there is no such attribute (SCAP_BND) in TIMES.  There is a variable VAR_SCAP(r,v,t,p), which represents the cumulative amount of retirements for vintage v in period t, but there is no input attribute for bounding this variable, and you did not want to bound retirements by vintage anyway.

In principle, a new attribute for bounding the cumulative retirements over all vintages in a given period would be possible to implement, if such would be considered useful.  However, I have some doubts about its usefulness, because the "over all vintages" is somewhat ambiguous and would depend on the period definition, if limited to those vintages that happen to have their original lifetime overlapping the period or including the milestone year...
Reply
#3
Some additional remarks:

As you say that you "receive the number of vehicle sales and vehicle scrappage on an annual level", would that mean that you can calculate the remaining amount of vehicles for each year by subtracting the cumulative scrappage from the cumulative sales?  If so, you can easily bound the capacity in each milestone year to that value, CAP_BND(r,t,p,BD) = value, with BD=UP/FX,which would implicitly cause scrapping at the desired amount, but of course only at the milestone years.

Note also that if you are indeed defining NCAP_PASTI for each individual year within the active model horizon, the original design of TIMES would not respect all those commissioning years accurately. But there is a way to enable accurate handling of such NCAP_PASTI vintages, by defining INT_DEFAULT('PASTI') = yes.  That will be automatically set also if you define any value NCAP_PASTI(r,'0',p). According to the original design, NCAP_PASTI was supposed to be defined only for years before the first model period.
Reply
#4
Dear Antti

Thank you so much for your useful feedback. Indeed I meant in my previous comment the VAR_SCAP and not SCAP_BND. However, I think your following remarks are most relevant to solve my problem:

(19-05-2022, 10:04 PM)Antti-L Wrote: As you say that you "receive the number of vehicle sales and vehicle scrappage on an annual level", would that mean that you can calculate the remaining amount of vehicles for each year by subtracting the cumulative scrappage from the cumulative sales?  If so, you can easily bound the capacity in each milestone year to that value, CAP_BND(r,t,p,BD) = value, with BD=UP/FX,which would implicitly cause scrapping at the desired amount, but of course only at the milestone years.
This is indeed a good suggestion. As you say, it should in principle be possible to implicitly include the scrapping by defining the annual sales (NCAP_PASTI for each year) and the entire vehicle stock (CAP_BND in the milestone year).

(19-05-2022, 10:04 PM)Antti-L Wrote: Note also that if you are indeed defining NCAP_PASTI for each individual year within the active model horizon, the original design of TIMES would not respect all those commissioning years accurately. But there is a way to enable accurate handling of such NCAP_PASTI vintages, by defining INT_DEFAULT('PASTI') = yes.  That will be automatically set also if you define any value NCAP_PASTI(r,'0',p).  According to the original design, NCAP_PASTI was supposed to be defined only for years before the first model period.
This is a very useful information that I was not aware of yet! For the model coupling, I usually do not touch the files of the existing model in VEDA-FE but directly compute the .dd-files based on the input data of the external model and adjust the .RUN file. I tried to implement NCAP_PASTI(r,'0',p) in a scenario file of a small testmodel (see attached screenshot) and create the .dd- and .RUN-files through VFE, but I could not find where INT_DEFAULT('PASTI') = yes is defined. Could you therefore please specify where and how INT_DEFAULT('PASTI') = yes will be defined? Is this a option that will be written as a "SET" into the .RUN-file? If yes, how exactly would the code line look like that I need to add to the .RUN file?

Kind regards,
Sandro


Attached Files Thumbnail(s)
   
Reply
#5
> Could you therefore please specify where and how INT_DEFAULT('PASTI') = yes will be defined?
 NCAP_PASTI(r,'0',p) causes INT_DEFAULT('PASTI') to be defined by the TIMES code when it is executed.

> Is this a option that will be written as a "SET" into the .RUN-file?
 The TFM_INS you have is sufficient, as long as the DD file where that NCAP_PASTI parameter is written is included in the model run.
Reply
#6
Dear Antti

I have tried to work with the NCAP_PASTI(r,'0',p) to define vehicle sales annually (my milestone years are 2020, 2030, 2040, 2050). However, once I activate the respective .dd-file, my model becomes infeasible. 


My .dd-file reads as follows:


Quote:$ONEMPTY
$ONEPS
$ONWARNING
$SET RUN_NAME 'STEM_PROBOUND_single_files'
$SET SCENARIO_NAME 'xt_8clu_car_annualsales_enabler'
SET TOP_IRE
/
/

SET UC_N
/
/

PARAMETER
NCAP_PASTI ' '/
CH.0.T_C-ICEGSL_GHIT_EXT 1
CH.0.T_C-ICEDSL_GHIT_EXT 1
CH.0.T_C-ICENGA_GHIT_EXT 1
CH.0.T_C-HYBGSL_GHIT_EXT 1
CH.0.T_C-BATELC_GHIT_EXT 1
CH.0.T_C-ICEGSL_GHIO_EXT 1
CH.0.T_C-ICEDSL_GHIO_EXT 1
[...]

/


Does anything seem wrong to you? Or do you have perhaps another idea why this could lead to an infeasible model? If necessary, I can also add an excerpt from the .lst-file (I just don't have it accessible right now).

Kind regards,
Sandro
Reply
#7
Thanks for the problem report.  However, actually I said:

AL> That will be automatically set also if you define any value NCAP_PASTI(r,'0',p).

So, you would only need a single (any) NCAP_PASTI(r,'0',p) defined, to get the '0' included in PASTYEAR, which would activate INT_DEFAULT('PASTI').

Nonetheless, I have no idea why you get an infeasible model, without seeing a reproducible case.  Could you provide such?  The *.DD and *.RUN files for the infeasible case would be sufficient, if you can provide me them e.g. via Dropbox / Google drive. If providing these files is possible, you could send me the download link in a private message. Including the listing file might also be helpful.
Reply
#8
Hello Antti,

I am basically doing the same combination of NCAP_PASTI and CAP_BND definitions for existing ELC and CHP plants, with early retirements enabled.
I am using a modified version of the JRC-EU-TIMES model.
It used to work properly - LP status(1) - with the original definition of NCAP_PASTI for 1970, 1980, 1990,2000, 2010, 2015 and 2018 and CAP_BND for 2015 and 2018 (START YEAR in 2010)


I have now modified the NCAP_PASTI so that they extend for all years until 2023 and CAP_BND in 2015, 2019 and 2023 (with default migration to milestone years option). But now the LP status is 6 non optimal (Solution available but not proven optimal due to numerical difficulties) and TIMES Solve status is Intermediate nonoptimal. In the end, there are dummy imports everywhere.

Thinking that it could come from a mismatch between PASTI and CAP_BND, I deactivated the CAP_BND, letting only the PASTI and the early retirements possible. The LP status was 6 again, although the dummy imports were OK (almost the same as in the original run (previous NCAP_PASTI and CAP_BND)).

Do you know what could be the reason for these non-optimal solutions ? I can of course send you the .DD, .RUN and .LST file.

Thanks a lot for your help,
Vince


Attached Files Thumbnail(s)
           
Reply
#9
If Cplex says the model is feasible (but it only reaches a non-optimal solution), then it looks like just some numerical problem, probably unrelated to your PASTI & CAP_BND. But anyway, how about your RCAP_BND?  Can you post a picture showing all RCAP_BND parameters defined for these processes?  And which are your milestone years?

I am reluctant to investigate this issue with your multi-million row JRC-EU-TIMES model, because I know it is numerically a rather poorly behaving big model. However, if there is indeed some technical problem with this specification with the NCAP_PASTIs and CAP_BNDs with early retirements, you should be able to reproduce the problem with a small test model.  I would be happy to look into the problem with such an easily reproducible case.
Reply
#10
Hello Antti,

Thank you for your answer.
I attached a picture of the definition of the RCAP_BND (they are fixed to 0 until 2020 if there is no CAP_BND defined and until 2010 otherwise).
My milestone years are : 2010, 2012, 2016, 2020, 2025, 2030, 2040, 2050, 2060.

Indeed it says that the solution is not proven optimal due to numerical difficulties. But do you know why it could turn out to have such numerical difficulties only adding new PASTI ?

I will try to repoduce the problem on a small test model.

Thanks again,
Vince


Attached Files Thumbnail(s)
   
Reply
#11
For curiosity, I made some small tests:

First, I just tested (once again) with a simple test model this "bound with retirement" functionality in general (successive NCAP_PASTIs with retirements enabled and CAP_BND to bound the capacity to a level that requires some retirements), and could not see any problems in it.

Second, I tested your problem case (1), but with a horizon up to 2025 only (because I think your CAP_BNDs were directly affecting only Milestones up to 2025), and indeed I saw Cplex having severe problems with the model (barrier not converging), with status Feasible but (6) Non-optimal.

Third, I tested your problem case (1), with a horizon up to 2025, and with the CAP_BNDs of the scenario calibration_eepp-echp.dd changed to UP instead of fixed bounds.  And now, Cplex was able to solve the model with good convergence into optimality.

These tests did not reveal any problem in this functionality as such. However, the fact that the problem appeared to go away as soon as the CAP_BNDs were defined with an upper bound may indicate that some of your fixed CAP_BNDs may be causing some inconsistencies, which are probably very small because the model was still declared feasible by Cplex (although I have also seen that the status might change when using crossover, i.e. models might be found infeasible when requesting a more accurate solution by using crossover). Therefore, unless you think you really need to force the capacities exactly at the fixed values, I would suggest using upper bounds, or otherwise check all your fixed capacity bounds for consistency.

> But do you know why it could turn out to have such numerical difficulties only adding new PASTI ?

No, I don't.  I am inclined to think that it may be either 1) just a random numerical issues appearing in this numerically rather poorly behaving big JRC-EU-TIMES model, or 2) adding new NCAP_PASTI may perhaps affect the behaviour of some user constraints in this model (see e.g scenarios sepdb-ziet*) in undesirable ways. I don't really know this model too well, but I have seen that quite a few constraints in it are indeed prone to causing problems.
Reply
#12
Dear Antti,

Blessed be your curiosity  Rolleyes . With your insight and a bit of digging, I managed to find out where the inconsistancy between the CAP_BND and PASTI went from.

Analyzing the results of the run with CAP_BND UP instead of FX, I realized that the Vintage 0 of VAR_CAP was not equal to what I was thinking for the milestone year 2020. It was slightly lower than the sum of all the PASTI from 1970 to 2020, which was my assumption when I made the calculation to fix the CAP_BND. It was not surprising, therefore, that the CAP_BND LO I was imposing was sometimes unreachable.

I tried to make the calculation to understand the PASTI and VAR_CAP handling within periods. Reading the documentation, I did not find much information on PASTI after the Start Year, but I thought it could be the same logic as described for NCAP.
Here is what I understood : for instance if I put a PASTI of 1 GW in 2020 in a period going from 2018 to 2022, I though it could be available 3/5 of the time period (from 2020 to 2022), so the Var_CAP Vintage 0 in the results would be 3/5 = 0.6 GW. However what I see in the results is more 0,5705... Do you know the logic behind ?

I also digged into the great many UC on the power system that are defined in this model and changed a bit the active years of these constraints in order not to trigger useless dummy imports at the beggining of the modelling horizon, and gain a bit of calculation time. 

Thanks again Antti !

Vince
Reply
#13
> for instance if I put a PASTI of 1 GW in 2020 in a period going from 2018 to 2022, I though it could be available 3/5 of the time period (from 2020 to 2022), so the Var_CAP Vintage 0 in the results would be 3/5 = 0.6 GW. However what I see in the results is more 0,5705... Do you know the logic behind ?

Sure, I confess having designed that logic myself.  Blush

It is because 3/5 would not be economically consistent.  Crediting for 3/5 of the capacity would give more value for the capacity than what the true value is (3 last years of the 5-year period). The economically correct value is obtained by taking the discounted fraction of the capacity available in the period.  With your 5% discount rate, the discounted value of that capacity is the said fraction (0,5705) of the PASTI value.  I think this method is fully justified, although it may not look quite as intuitive as the "undiscounted" value 3/5. It is mostly of importance for new investments, where crediting with the "undiscounted" fraction would to some extent distort the profitability of investments (you might get too much value from some investments, and too little from others), but surely also the value of past investments would be likewise distorted.
Reply
#14
Oh I understand, perfectly clear.
Indeed that makes a lot of sense for new investments decision.
Thank you !
Vince
Reply
#15
Hello,
I have another questions (for Amit, I guess Wink ) on NCAP_PASTI management for years within the active model horizon.
I made a little test model to see the effect of defining NCAP_PASTI(r,'0'',p) = 1 for a given process having PASTI within the model horizon. I tested 3 different cases :
  • Case 1 : One with NCAP_PASTI(r,'0'',p) = 1 for the process p = TCANDSL1 only

  • Case 2 : One with NCAP_PASTI(r,'0'',p) = 1 for the process p = ELCREHYD00 only

  • Case 3 : One with no NCAP_PASTI(r,'0'',p) defined.


I looked at the results for TCANDSL1. Case 1 and 2 give exactly the same results, so, as you explained previously several times : defining NCAP_PASTI(r,'0'',p) for only one process (p) and one region ® makes the option INT_DEFAULT('PASTI') active for the whole model, so the management of NCAP_PASTI would be handled accurately for any process and any region.
However, I noticed that in these two cases, there is no vintage for years corresponding to the milestones years within the model horizon, although PASTI are defined for these years. These particular vintages seem to be accounted for at the year just before. For instance, a PASTI defined in year 2012, which is also a milestone year in this model, will be seen (looking at cost_fom for instance) in vintage = 2011. This is not the case in Case 3 where no NCAP_PASTI(r,'0'',p) is defined. So, I guess this must be part of the accurate handling of PASTI coming after the Start Year of the model. But I wanted to understand what is the logic behind if possible.

Thanks a lot !
Vince
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)