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

Add variant/module for cooling technologies in tools.costs #222

Merged
merged 11 commits into from
Oct 23, 2024
14 changes: 11 additions & 3 deletions doc/api/tools-costs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ Currently, :mod:`.tools.costs` supports two module :attr:`~.Config.module` setti
"materials"
Technologies conceived as part of the materials and industry sectors.

"cooling"
Cooling technologies for power plants.

Data and files for a particular module can refer to other modules.
This allows for values or settings for "materials" and other technologies to be assumed to match the values and settings used for the referenced "energy"-module technologies.

Expand Down Expand Up @@ -86,9 +89,9 @@ To add a new module, the following steps are required:
Please note that the following assumptions are made in technology costs mapping:

- If a technology is mapped to a technology in the "energy" module, then the cost reduction across scenarios is the same as the cost reduction of the mapped technology.
- If a "materials" (or any other non-"energy") technology has :py:`reg_diff_source="energy"` and the "base_year_reference_region_cost" is not empty, then the "base_year_reference_region_cost" in :file:`tech_map_[module].csv` is used as the base year cost for the technology in the reference region.
- If a non-"energy" module (such as "materials" or "cooling") technology has :py:`reg_diff_source="energy"` and the "base_year_reference_region_cost" is not empty, then the "base_year_reference_region_cost" in :file:`tech_map_[module].csv` is used as the base year cost for the technology in the reference region.
If the "base_year_reference_region_cost" is empty, then the cost reduction across scenarios is the same as the cost reduction of the mapped technology.
- If using the "materials" module, if a technology that is specified in :file:`tech_map_materials.csv` already exists in :file:`tech_map_energy.csv`, then the reference region cost is taken from :file:`tech_map_materials.csv`.
- If using a non-"energy" module (such as "materials" or "cooling"), if a technology that is specified in :file:`tech_map_materials.csv` already exists in :file:`tech_map_energy.csv`, then the reference region cost is taken from :file:`tech_map_materials.csv`.
- If a technology in a module is not mapped to any source of regional differentiation, then no cost reduction over the years is applied to the technology.
- If a technology has a non-empty "base_year_reference_region_cost" but is not mapped to any source of regional differentiation, then assume no regional differentiation and use the reference region base year cost as the base year cost for all regions.

Expand Down Expand Up @@ -145,6 +148,11 @@ These data can be further manipulated; for instance, added to a scenario using :
See the file :file:`message_ix_models/tools/costs/demo.py` for multiple examples using various non-default settings to control the methods and data used by :func:`.create_cost_projections`.


.. note:: The data produced are for all valid combinations of :math:`(y^V, y^A)`—including those that are beyond the `technical_lifetime` of the |t| to which they apply.
This may produce large data frames, depending on the number of technologies, regions, and scenarios.
At the moment, :mod:`.tools.costs` does not filter out these combinations.
If this is problematic, the user may consider filtering the data for valid combinations of :math:`(y^V, y^A)`.

Code reference
==============

Expand Down Expand Up @@ -222,7 +230,7 @@ Regional differentiation of costs (:mod:`~.costs.regional_differentiation`)
get_weo_data
get_intratec_data
get_raw_technology_mapping
subset_materials_map
subset_module_map
adjust_technology_mapping
get_weo_regional_differentiation
get_intratec_regional_differentiation
Expand Down
3 changes: 2 additions & 1 deletion doc/whatsnew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ Next release
- Expand :doc:`repro` with sections on :ref:`repro-doc` and :ref:`versioning`, including :ref:`a list of external model names and ‘versions’ <model-names>` like “MESSAGEix-GLOBIOM 2.0” (:issue:`224`, :pull:`226`).
- Update :doc:`/transport/index` (:pull:`213`).
- Add "LED", "SSP4", and "SSP5" as values for the :program:`--ssp=…` option in :func:`.common_params` (:pull:`233`).
- Fix and update :doc:`/api/tools-costs` (:pull:`219`, :pull:`206`, :pull:`221`)
- Fix and update :doc:`/api/tools-costs` (:pull:`219`, :pull:`206`, :pull:`221`, :pull:`227`, :pull:`222`)

- Fix naming of GDP and population columns in SSP data aggregation (:pull:`219`).
- Edit inputs for storage, CSP, hydrogen, and industry technologies (:pull:`206`).
- Replace solar and wind technologies with new ones (:pull:`206`).
- Reorganize input files and incorporate `first_year.csv` data into `tech_map.csv` (:pull:`221`).
- Reconfigure use and implementation of technology variants/modules to be more agnostic (:pull:`221`).
- Change cost decay to reach reduction percentage specified on the year 2100 (:pull:`227`).
- Add `cooling` technology variant/module (:pull:`222`).
- Improve and extend :doc:`/material/index` (:pull:`218`).

- Release of MESSAGEix-Materials 1.1.0 (:doc:`/material/v1.1.0`).
Expand Down
93 changes: 93 additions & 0 deletions message_ix_models/data/costs/cooling/tech_map.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
message_technology,reg_diff_source,reg_diff_technology,base_year_reference_region_cost,fix_ratio,first_year_original
bio_hpl__air,energy,bio_hpl,220,0,2015
bio_hpl__cl_fresh,energy,bio_hpl,100,0,2015
bio_hpl__ot_fresh,energy,bio_hpl,0.4,0,2015
bio_hpl__ot_saline,energy,bio_hpl,0.3,0,2015
bio_istig__air,energy,bio_istig,220,0,2015
bio_istig__cl_fresh,energy,bio_istig,100,0,2015
bio_istig__ot_fresh,energy,bio_istig,0.4,0,2015
bio_istig__ot_saline,energy,bio_istig,0.3,0,2015
bio_istig_ccs__air,energy,bio_istig_ccs,220,0,2015
bio_istig_ccs__cl_fresh,energy,bio_istig_ccs,100,0,2015
bio_istig_ccs__ot_fresh,energy,bio_istig_ccs,0.4,0,2015
bio_istig_ccs__ot_saline,energy,bio_istig_ccs,0.3,0,2015
bio_ppl__air,energy,bio_ppl,220,0,2015
bio_ppl__cl_fresh,energy,bio_ppl,100,0,2015
bio_ppl__ot_fresh,energy,bio_ppl,0.4,0,2015
bio_ppl__ot_saline,energy,bio_ppl,0.3,0,2015
coal_adv__air,energy,coal_adv,220,0,2015
coal_adv__cl_fresh,energy,coal_adv,100,0,2015
coal_adv__ot_fresh,energy,coal_adv,0.4,0,2015
coal_adv__ot_saline,energy,coal_adv,0.3,0,2015
coal_adv_ccs__air,energy,coal_adv_ccs,220,0,2015
coal_adv_ccs__cl_fresh,energy,coal_adv_ccs,160,0,2015
coal_adv_ccs__ot_fresh,energy,coal_adv_ccs,0.4,0,2015
coal_adv_ccs__ot_saline,energy,coal_adv_ccs,0.3,0,2015
coal_ppl__air,energy,coal_ppl,220,0,2015
coal_ppl__cl_fresh,energy,coal_ppl,100,0,2015
coal_ppl__ot_fresh,energy,coal_ppl,0.4,0,2015
coal_ppl__ot_saline,energy,coal_ppl,0.3,0,2015
coal_ppl_u__air,energy,coal_ppl_u,220,0,2015
coal_ppl_u__cl_fresh,energy,coal_ppl_u,160,0,2015
coal_ppl_u__ot_fresh,energy,coal_ppl_u,0.4,0,2015
coal_ppl_u__ot_saline,energy,coal_ppl_u,0.3,0,2015
foil_hpl__air,energy,foil_hpl,220,0,2015
foil_hpl__cl_fresh,energy,foil_hpl,100,0,2015
foil_hpl__ot_fresh,energy,foil_hpl,0.4,0,2015
foil_hpl__ot_saline,energy,foil_hpl,0.3,0,2015
foil_ppl__air,energy,foil_ppl,220,0,2015
foil_ppl__cl_fresh,energy,foil_ppl,100,0,2015
foil_ppl__ot_fresh,energy,foil_ppl,0.4,0,2015
foil_ppl__ot_saline,energy,foil_ppl,0.3,0,2015
gas_cc__air,energy,gas_cc,140,0,2015
gas_cc__cl_fresh,energy,gas_cc,50,0,2015
gas_cc__ot_fresh,energy,gas_cc,0.2,0,2015
gas_cc__ot_saline,energy,gas_cc,0.15,0,2015
gas_cc_ccs__air,energy,gas_cc_ccs,220,0,2015
gas_cc_ccs__cl_fresh,energy,gas_cc_ccs,160,0,2015
gas_cc_ccs__ot_fresh,energy,gas_cc_ccs,0.4,0,2015
gas_cc_ccs__ot_saline,energy,gas_cc_ccs,0.3,0,2015
gas_hpl__air,energy,gas_hpl,220,0,2015
gas_hpl__cl_fresh,energy,gas_hpl,100,0,2015
gas_hpl__ot_fresh,energy,gas_hpl,0.4,0,2015
gas_hpl__ot_saline,energy,gas_hpl,0.3,0,2015
gas_ppl__air,energy,gas_ppl,220,0,2015
gas_ppl__cl_fresh,energy,gas_ppl,100,0,2015
gas_ppl__ot_fresh,energy,gas_ppl,0.4,0,2015
gas_ppl__ot_saline,energy,gas_ppl,0.3,0,2015
geo_hpl__air,energy,geo_hpl,220,0,2015
geo_hpl__cl_fresh,energy,geo_hpl,100,0,2015
geo_hpl__ot_fresh,energy,geo_hpl,0.4,0,2015
geo_hpl__ot_saline,energy,geo_hpl,0.3,0,2015
geo_ppl__air,energy,geo_ppl,220,0,2015
geo_ppl__cl_fresh,energy,geo_ppl,100,0,2015
geo_ppl__ot_fresh,energy,geo_ppl,0.4,0,2015
geo_ppl__ot_saline,energy,geo_ppl,0.3,0,2015
igcc__air,energy,igcc,140,0,2015
igcc__cl_fresh,energy,igcc,50,0,2015
igcc__ot_fresh,energy,igcc,0.4,0,2015
igcc__ot_saline,energy,igcc,0.3,0,2015
igcc_ccs__air,energy,igcc_ccs,220,0,2015
igcc_ccs__cl_fresh,energy,igcc_ccs,100,0,2015
igcc_ccs__ot_fresh,energy,igcc_ccs,0.4,0,2015
igcc_ccs__ot_saline,energy,igcc_ccs,0.3,0,2015
loil_cc__air,energy,loil_cc,140,0,2015
loil_cc__cl_fresh,energy,loil_cc,50,0,2015
loil_cc__ot_fresh,energy,loil_cc,0.2,0,2015
loil_cc__ot_saline,energy,loil_cc,0.3,0,2015
loil_ppl__air,energy,loil_ppl,220,0,2015
loil_ppl__cl_fresh,energy,loil_ppl,100,0,2015
loil_ppl__ot_fresh,energy,loil_ppl,0.4,0,2015
loil_ppl__ot_saline,energy,loil_ppl,0.3,0,2015
nuc_hc__air,energy,nuc_hc,220,0,2015
nuc_hc__cl_fresh,energy,nuc_hc,100,0,2015
nuc_hc__ot_fresh,energy,nuc_hc,0.4,0,2015
nuc_hc__ot_saline,energy,nuc_hc,0.3,0,2015
nuc_lc__air,energy,nuc_lc,220,0,2015
nuc_lc__cl_fresh,energy,nuc_lc,160,0,2015
nuc_lc__ot_fresh,energy,nuc_lc,0.8,0,2015
nuc_lc__ot_saline,energy,nuc_lc,0.6,0,2015
solar_th_ppl__air,energy,solar_th_ppl,220,0,2015
solar_th_ppl__cl_fresh,energy,solar_th_ppl,100,0,2015
solar_th_ppl__ot_fresh,energy,solar_th_ppl,0.4,0,2015
solar_th_ppl__ot_saline,energy,solar_th_ppl,0.3,0,2015
6 changes: 4 additions & 2 deletions message_ix_models/tests/tools/costs/test_decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
(
("energy", {"coal_ppl", "gas_ppl", "gas_cc", "solar_res1"}),
("materials", {"biomass_NH3", "MTO_petro", "furnace_foil_steel"}),
("cooling", {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}),
),
)
def test_get_cost_reduction_data(module: str, t_exp) -> None:
Expand All @@ -32,7 +33,7 @@ def test_get_cost_reduction_data(module: str, t_exp) -> None:
assert 0 <= stats["min"] and stats["max"] <= 1


@pytest.mark.parametrize("module", ("energy", "materials"))
@pytest.mark.parametrize("module", ("energy", "materials", "cooling"))
def test_get_technology_reduction_scenarios_data(module: str) -> None:
config = Config()
# The function runs without error
Expand All @@ -57,10 +58,11 @@ def test_get_technology_reduction_scenarios_data(module: str) -> None:
{"biomass_NH3"},
),
("materials", {"biomass_NH3", "MTO_petro", "furnace_foil_steel"}, set()),
("cooling", {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}, set()),
),
)
def test_project_ref_region_inv_costs_using_reduction_rates(
module: Literal["energy", "materials"], t_exp, t_excluded
module: Literal["energy", "materials", "cooling"], t_exp, t_excluded
) -> None:
# Set up
config = Config(module=module)
Expand Down
2 changes: 1 addition & 1 deletion message_ix_models/tests/tools/costs/test_gdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def test_process_raw_ssp_data(test_context, node) -> None:
assert scens == set(result.scenario.unique())


@pytest.mark.parametrize("module", ("energy", "materials"))
@pytest.mark.parametrize("module", ("energy", "materials", "cooling"))
def test_adjust_cost_ratios_with_gdp(test_context, module) -> None:
# Set parameters
test_context.model.regions = "R12"
Expand Down
5 changes: 5 additions & 0 deletions message_ix_models/tests/tools/costs/test_projections.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
}
},
),
(
Config(module="cooling", method="gdp", node="R12", scenario="SSP5"),
{"technology": {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}},
{"technology": {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}},
),
pytest.param(
Config(node="R20"),
set(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ def test_get_intratec_data() -> None:
(
("energy", {"coal_ppl", "gas_ppl", "gas_cc", "solar_res1"}, {"weo"}),
("materials", {"biomass_NH3", "meth_h2", "furnace_foil_steel"}, {"energy"}),
(
"cooling",
{"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"},
{"energy"},
),
),
)
def test_get_raw_technology_mapping(module, t_exp, rds_exp) -> None:
Expand All @@ -87,7 +92,7 @@ def test_get_raw_technology_mapping(module, t_exp, rds_exp) -> None:
assert rds_exp <= set(result.reg_diff_source.unique())


@pytest.mark.parametrize("module", ("energy", "materials"))
@pytest.mark.parametrize("module", ("energy", "materials", "cooling"))
def test_adjust_technology_mapping(module) -> None:
energy_raw = get_raw_technology_mapping("energy")

Expand All @@ -110,6 +115,7 @@ def test_adjust_technology_mapping(module) -> None:
(
("energy", {"coal_ppl", "gas_ppl", "gas_cc", "solar_res1"}),
("materials", {"biomass_NH3", "meth_h2", "furnace_foil_steel"}),
("cooling", {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}),
),
)
def test_apply_regional_differentiation(module, t_exp) -> None:
Expand Down
2 changes: 1 addition & 1 deletion message_ix_models/tools/costs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Config:
method: Literal["constant", "convergence", "gdp"] = "gdp"

#: Model variant for which to project costs.
module: Literal["energy", "materials"] = "energy"
module: Literal["energy", "materials", "cooling"] = "energy"

#: Use vintages.
#:
Expand Down
4 changes: 2 additions & 2 deletions message_ix_models/tools/costs/regional_differentiation.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def get_intratec_data() -> pd.DataFrame:


def get_raw_technology_mapping(
module: Literal["energy", "materials"],
module: Literal["energy", "materials", "cooling"],
) -> pd.DataFrame:
"""Retrieve a technology mapping for `module`.

Expand Down Expand Up @@ -234,7 +234,7 @@ def subset_module_map(raw_map):


def adjust_technology_mapping(
module: Literal["energy", "materials"],
module: Literal["energy", "materials", "cooling"],
) -> pd.DataFrame:
"""Adjust technology mapping based on sources and assumptions.

Expand Down
Loading