When generate_report() is run with a subset of regions via desired_regions, the resulting Capacity|Electricity|* values for the selected regions are inflated by roughly 7x–60x compared to the same region in an all-regions run. Running with desired_regions = "All" gives correct, realistic capacities.
Observed behavior
Same single scenario, same region (South Korea), same GCAM_version = "v7.0", same database. The only difference is desired_regions. Values in GW, year 2020:
| Variable |
desired_regions = "All" |
desired_regions = c("South Korea","Russia") |
ratio |
Capacity|Electricity (total) |
153.0 |
3091.3 |
20.2x |
Capacity|Electricity|Coal |
39.8 |
1139.7 |
28.6x |
Capacity|Electricity|Gas |
65.6 |
595.2 |
9.1x |
Capacity|Electricity|Nuclear |
22.9 |
162.7 |
7.1x |
Capacity|Electricity|Solar |
14.5 |
655.1 |
45.2x |
Capacity|Electricity|Wind |
3.4 |
199.3 |
58.2x |
The "All" column matches real South Korea installed capacity well (≈150 GW total, ≈40 GW coal, ≈23 GW nuclear, ≈15 GW solar in 2020). The subset column is physically impossible. The inflation grows as fewer regions are selected.
Root cause
In get_cf_iea_tmp() (R/functions.R), the IEA-consistent capacity factor is
cf = EJ / (value * hr_per_yr * EJ_to_GWh)
where the numerator and denominator are computed at different region scopes:
-
Numerator EJ comes from secondary_energy_clean, summed by technology:
tmp1 <- secondary_energy_clean %>%
dplyr::filter(year == base_year_p, scenario == unique(secondary_energy_clean$scenario)[1]) %>%
dplyr::group_by(var) %>%
dplyr::summarise(EJ = sum(value, na.rm = T))
secondary_energy_clean only contains the regions present in the project, so when desired_regions is a subset this sum is the generation of only those regions.
-
Denominator value comes from iea_capacity, which is provided only for region "World" (global installed capacity, region-independent and fixed):
tmp2 <- iea_capacity %>%
dplyr::filter(period == base_year_p, scenario == "Current Policies Scenario")
So selecting fewer regions shrinks the numerator (less generation) while the denominator stays at the global World capacity. cf_iea therefore comes out far too small, and since downstream capacity is generation / (cf * ...) (get_elec_capacity_tot()), the reported capacity explodes. The approximate inflation factor is (world generation) / (selected-region generation), which is consistent with the 7x–60x range above.
cf_iea is intended to be a single global (world-average) capacity factor, so the numerator must be world generation. With a region-filtered project, the world generation is simply not available, which is what breaks the calculation.
How to reproduce
# Correct
generate_report(db_path, db_name, scenarios = <scenario>,
GCAM_version = "v7.0", desired_regions = "All",
desired_variables = "Capacity*")
# Inflated — compare South Korea Capacity|Electricity between the two
generate_report(db_path, db_name, scenarios = <scenario>,
GCAM_version = "v7.0", desired_regions = c("South Korea", "Russia"),
desired_variables = "Capacity*")
Confirmed on v7.0. Because iea_capacity is World-only for every version, the
same scope mismatch should affect all GCAM versions.
Possible fixes
The proper fix is a design decision, so we would like your input before sending a PR:
- Compute the
cf_iea numerator from global base-year generation regardless of desired_regions (e.g. always query/keep world secondary energy, or bundle a precomputed global base-year generation so cf_iea is region-independent by construction), or
- Restrict
Capacity|Electricity to desired_regions = "All" and clearly document (and warn) that capacity is not valid for region subsets.
Happy to help with a PR if useful.
When
generate_report()is run with a subset of regions viadesired_regions, the resultingCapacity|Electricity|*values for the selected regions are inflated by roughly 7x–60x compared to the same region in an all-regions run. Running withdesired_regions = "All"gives correct, realistic capacities.Observed behavior
Same single scenario, same region (
South Korea), sameGCAM_version = "v7.0", same database. The only difference isdesired_regions. Values in GW, year 2020:desired_regions = "All"desired_regions = c("South Korea","Russia")Capacity|Electricity(total)Capacity|Electricity|CoalCapacity|Electricity|GasCapacity|Electricity|NuclearCapacity|Electricity|SolarCapacity|Electricity|WindThe
"All"column matches real South Korea installed capacity well (≈150 GW total, ≈40 GW coal, ≈23 GW nuclear, ≈15 GW solar in 2020). The subset column is physically impossible. The inflation grows as fewer regions are selected.Root cause
In
get_cf_iea_tmp()(R/functions.R), the IEA-consistent capacity factor iswhere the numerator and denominator are computed at different region scopes:
Numerator
EJcomes fromsecondary_energy_clean, summed by technology:secondary_energy_cleanonly contains the regions present in the project, so whendesired_regionsis a subset this sum is the generation of only those regions.Denominator
valuecomes fromiea_capacity, which is provided only for region"World"(global installed capacity, region-independent and fixed):So selecting fewer regions shrinks the numerator (less generation) while the denominator stays at the global World capacity.
cf_ieatherefore comes out far too small, and since downstream capacity isgeneration / (cf * ...)(get_elec_capacity_tot()), the reported capacity explodes. The approximate inflation factor is(world generation) / (selected-region generation), which is consistent with the 7x–60x range above.cf_ieais intended to be a single global (world-average) capacity factor, so the numerator must be world generation. With a region-filtered project, the world generation is simply not available, which is what breaks the calculation.How to reproduce
Confirmed on
v7.0. Becauseiea_capacityis World-only for every version, thesame scope mismatch should affect all GCAM versions.
Possible fixes
The proper fix is a design decision, so we would like your input before sending a PR:
cf_ieanumerator from global base-year generation regardless ofdesired_regions(e.g. always query/keep world secondary energy, or bundle a precomputed global base-year generation socf_ieais region-independent by construction), orCapacity|Electricitytodesired_regions = "All"and clearly document (and warn) that capacity is not valid for region subsets.Happy to help with a PR if useful.