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

Made changes to tools.costs related to base year and first year of modeling #186

Merged
merged 11 commits into from
Apr 25, 2024

Conversation

measrainsey
Copy link
Contributor

@measrainsey measrainsey commented Apr 24, 2024

Made a number of changes to tools.costs, mostly relating to the modeling of base year, first model year, and first technology year

To summarize, the changes are:

  • Fixed jumps in cost projections for technologies with first technology year that's after than the first model year (addresses issue Fix odd tools.costs projections for technologies with first years in the future #169) and remove projections for years that are before a technology's "first_technology_year"
  • Changed the use of base_year to mean the year to start modeling cost changes
  • Update cost assumptions for certain CCS technologies
  • Changed the default fixed O&M reduction rate (fom_rate) to 0

Additional details relevant to each change found below.

How to review

For @khaeru and/or @glatterf42 : Read the diff and note that the CI checks all pass.

PR checklist

  • Continuous integration checks all ✅
  • Update doc/whatsnew.

Additional information

Fixed jumps in cost projections for technologies with later first technology year

Issue #169 described an issue with certain technologies that have a "first_technology_year" that's after the first model year (2020) behaving weirdly -- namely, the costs would jump up and then come back down to base year costs when it reaches its "first_technology_year". I've fixed this issue, so that the costs are projected just like other technologies (starting from the base year). Additionally, I've removed projections for years that are before the technology's "first_technology_year" completely. The "first_technology_year" refers to the first year a technology starts being deployed within MESSAGE. There's no other place this concept is used I think, so there's no other way to constrain it. So, I decided to filter out those years to avoid giving the model costs for years where the technology shouldn't even be in operation.

Using the same example as issue #169, here's how the investment cost projections for bio_istig_ccs looks now:
bio_istig_ccs

Modified the usage of base_year in the module

Previously, the base_year was mainly just used to decide what year WEO data to use. Now, I've changed the module to use 2021 WEO data no matter what, and base_year means the year to start projecting cost changes/reductions. base_year does not have to equal the first model year (y0). If base_year is after y0, then the technology's costs is held constant at the base year cost until y0. Note that this means there will be no cost variance across scenarios until base_year, but there will still be regional differentiation. I've changed the default base_year to 2025, holding the cost across scenarios constant from y0 (2020) to 2025 (so forcing no scenario variance from 2020 to 2025).

Example of this in action:

coal_ppl

Updated cost assumptions for certain CCS technologies

@OFR-IIASA, @gidden, and others have noted that there are some cases with a CCS technology's costs would dip lower than its non-CCS variant. The reason for that is that based on the inputs into the cost module, since these are two different technologies, there is nothing stopping their assumptions from causing them to have completely different pathways. Using syn_liq and syn_liq_ccs as examples: for the regional differentation, syn_liq was being mapped to IGCC in the WEO, while syn_liq_ccs was mapped to IGCC with CCS. If WEO has different regional differentations for their two technologies (which they do), then that affects how our costs for syn_liq and syn_liq_ccs. Additionally, syn_liq and syn_liq_ccs were following different cost reduction pathways and narratives. The combinations of these issues caused the costs of syn_liq_ccs in some regions to dip lower than syn_liq, which doesn't make sense.

syn_liq_old

The list of problematic technologies found in the cost module where this phenomenon occurs are:

  • h2_bio_ccs
  • h2_coal_ccs
  • liq_bio_ccs
  • meth_coal_ccs
  • meth_ng_ccs
  • syn_liq_ccs

For the listed technologies above, I made the following changes to their data inputs:

  • I changed the technology mapping so they are mapped to the same technology as their non-CCS variant
  • I copied over the same scenario reduction rates and narratives from their non-CCS variant

Here is what syn_liq_ccs costs look like after the changes:

syn_liq_new

Longer term we are having discussions on if we want to move to component-based modeling of CCS components and adding that cost onto the original technology.

Changed the default fixed O&M reduction rate (fom_rate) to 0

@macflo8 took a look at solar_pv_ppl costs over time and noted that fixed O&M costs were increasing too rapidly, causing solar to be deployed at very slow rates. This is due to the default fom_rate in the module being 0.025, which is applied universally to all technologies. For now I've just changed this to zero, which means for each year_vtg, the costs remain the same across all year_act. Longer term I need to look at making this configurable for specific technologies (some have lower or higher values) -- perhaps this can just be an input similar to the base year reference region costs.

By default, do not allow for the growth of fixed O&M costs (per vintage) over time

I also had to force the `config.fom_rate` in the equation to a float, otherwise I received this error:

``ValueError: Integers to negative integer powers are not allowed.``
Instead of projecting cost reductions starting at the model start year (`y0`), I've now changed the tool to start projecting at the base year (`base_year`). If `base_year` is greater than `y0` (which is 2020), the base year cost is held constant from `y0` to `base_year`.
We were seeing instances where the costs of certain CCS technologies were becoming lower than their non-CCS counterparts.

As a fix for now, I am manually changing the input assumptions for these technologies so that:
1) the CCS and non-CCS counterparts are mapped to the same WEO technologies (and therefore use the same regional differentiation)
2) the CCS technologies follow the same cost reduction narratives as their non-CCS counterparts
Copy link

codecov bot commented Apr 24, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 76.7%. Comparing base (38aa6e9) to head (48ccf0b).
Report is 2466 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##            main    #186     +/-   ##
=======================================
- Coverage   76.7%   76.7%   -0.1%     
=======================================
  Files        112     112             
  Lines       7154    7154             
=======================================
- Hits        5494    5491      -3     
- Misses      1660    1663      +3     
Files with missing lines Coverage Δ
message_ix_models/tests/tools/costs/test_decay.py 100.0% <100.0%> (ø)
message_ix_models/tools/costs/config.py 97.2% <100.0%> (ø)
message_ix_models/tools/costs/decay.py 100.0% <100.0%> (ø)
message_ix_models/tools/costs/demo.py 0.0% <ø> (ø)
message_ix_models/tools/costs/projections.py 84.7% <ø> (ø)
..._ix_models/tools/costs/regional_differentiation.py 97.9% <100.0%> (-0.1%) ⬇️

... and 1 file with indirect coverage changes

@measrainsey measrainsey self-assigned this Apr 24, 2024
Copy link
Member

@glatterf42 glatterf42 left a comment

Choose a reason for hiding this comment

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

Looks good to me, thanks :)
I'll approve once the docs-comments are addressed :)

doc/whatsnew.rst Outdated Show resolved Hide resolved
doc/whatsnew.rst Outdated Show resolved Hide resolved
Copy link
Member

@glatterf42 glatterf42 left a comment

Choose a reason for hiding this comment

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

Looks good to me now :)

@measrainsey measrainsey merged commit 16029b4 into main Apr 25, 2024
26 checks passed
@measrainsey measrainsey deleted the costs/first-year branch April 25, 2024 06:44
@@ -458,8 +468,21 @@ def create_message_outputs(
)
.astype(dtypes)
.query("year_vtg in @config.Y")
.assign(first_technology_year=lambda x: x.first_technology_year.astype(float))
.assign(first_technology_year=lambda x: x.first_technology_year.astype(int))
Copy link
Member

Choose a reason for hiding this comment

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

Is there any specific need for these two chained calls instead of directly?

.astype({"first_technology_year": int})

If there is, it would be good to record in a comment so people maintaining the code can understand why.

.reset_index(drop=True)
.drop_duplicates()
.drop_duplicates()[
[
Copy link
Member

Choose a reason for hiding this comment

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

AFAICT the intent of this selection is to drop the added column "first_technology_year". If so, then:

.drop("first_technology_year", axis=1)

…is more explicit and less noisy. Recall we made several adjustments like this in #99.

measrainsey added a commit that referenced this pull request Apr 25, 2024
@measrainsey measrainsey mentioned this pull request Apr 25, 2024
2 tasks
@khaeru khaeru mentioned this pull request Apr 26, 2024
2 tasks
@khaeru khaeru added the costs `.tools.costs`/cost data preparation label Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
costs `.tools.costs`/cost data preparation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants