message_ix
message_ix copied to clipboard
Incorrect definition of `map_tec_lifetime` due to parametrization requirements of `technical_lifetime`
map_tec_lifetime is a set created as part of data_loead.gms. It partly relies on the parameter technical_lifetime. The issue is that technical_lifetime needs to be defined for all activity years (the exact reason is unknown at this point in time). What this means: a powerplant which is phased out and can only be built until e.g. the vtg_year 2040 (see global model coal_ppl in NAM, PAO, WEU) has parameters defined until year_act 2060 and hence also requires the technical_lifetime to be defined for the vtg_years until 2060. This results in map_tec_lifetime creating entries for the vintages > 2040, which is unintended. The result, a powerplant can be built despite not having input/output defined which can happen if for example there is a relation activity entry, which is vintage independent.
Code sample or context
see map_tec_lifetime for coal_ppl in any given global MESSAGEix scenario. Entries exist for vintages post 2040, although input/output parameters exist only for the vintage 2040. the technical_lifetime entries post 2040 should be removed to get the correct entries. Doing so results in a GAMS error.
df = scen.par("technical_lifetime", {"technology": "coal_ppl", "node_loc": "R11_NAM"})
yr_max = max(scen.par("input", {"technology": "coal_ppl", "node_loc": "R11_NAM"}).year_vtg)
df = df[df.year_vtg > yr_max]
scen.check_out()
scen.remove_par("technical_lifetime", df)
scen.commit("")
scen.solve()
Problem description
--- MESSAGE_run.gms(1877) 425 Mb
Error: Technical lifetime not defined for 'R11_NAM|coal_ppl|2045' !
Error: Technical lifetime not defined for 'R11_NAM|coal_ppl|2050' !
Error: Technical lifetime not defined for 'R11_NAM|coal_ppl|2055' !
Error: Technical lifetime not defined for 'R11_NAM|coal_ppl|2060' !
Error: Technical lifetime not defined for 'R11_NAM|coal_ppl|2070' !
--- MESSAGE_run.gms(1883) 425 Mb
*** Error at line 1884: Execution halted: abort 'There is a problem with the definition of the technical lifetime!'
Versions
Output of message-ix show-versions
<!--
Run one of the following and paste the results here:
- 'message-ix show-versions' in a terminal, or
- 'import ixmp; ixmp.show_versions()' in a Python interpreter.
-->
Thanks @oliverfricko and everyone for the thoughts. I just summarize what was mentioned above:
- The issue in short is that the GAMS formulation rebuilds the vintaging (combination of vintage and active years) of a technology based on
technical_lifetime, irrespective of entries in the vintage-based parameters (e.g.,input,output,capacity_factor, etc.) for that technology. - Due to No. 1, it is not possible to represent technologies phasing out during the model periods, i.e., not lasting until the last model year, with the last vintage year being different from the last active year. For example, one cannot model a technology with the last vintage year 2040 remaining active until 2070. The GAMS formulation turns this example to the last vintage and active years bot being 2070.
- The current GAMS formulation, as well the python side (ixmp), does not check if the entries to vintage-based parameters of a technology are consistent with
technical_lifetimeof that technology or not. This check can be added, at least to throw a warning if not an error. - The GAMS formulation seems to have had a check related to this issue. But for a reason that is not clear, this check is currently commented out.
As per discussion between VK, DH, LW and OF:
The current definition of map_tec_lifetime is in line with the originally design. In addition to input/output being determining a technologies activity across different vintages, the vintage independent relations are also considered.
The two follow up tasks:
- [ ] Update the documentation to clearly describe the above behavior.
- [ ] Add two new parameters to the GAMS formulation which specify the first and last year in which investments can be made. e.g.
inv_fyear/inv_lyear
@danielhuppmann, as discussed in our meeting, would you be able to add a couple of paragraphs to describe the current behavior of MESSAGEix to the documentation. In my view this fit best in the mapping sets section (https://docs.messageix.org/en/stable/model/MESSAGE/sets_maps_def.html#section-maps-def).
map_tec_lifetimeis a set created as part of data_loead.gms. It partly relies on the parametertechnical_lifetime. The issue is thattechnical_lifetimeneeds to be defined for all activity years (the exact reason is unknown at this point in time).
Will it be possible for anyone to clarify this reason for having technical_lifetime based on year_act?
There are three determinants which define whether a technology gets assigned the map_tec_lifetime. input, output and relation_activity. relation_activity is vintage independent, hence the indication of the lifetime is needed for all activity years. So when map_tec_lifetime is populated for the example above, where input and output is only defined for the vintage 2040, the relation_activity is defined until 2070. The funny entries in map_tec_lifetime for the vintages > 2040, comes because there are no values defined for activity years > 2070. Hence the map_tec_lifetime entries for activity years, for the vintages > 2040, will all be cut off at 2070.
Any documentation or resolution here could hopefully also clarify/resolve #137 from 2018.