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

Correctly enforce existing capacities if build year >= base year #966

Closed
lindnemi opened this issue Mar 13, 2024 · 3 comments
Closed

Correctly enforce existing capacities if build year >= base year #966

lindnemi opened this issue Mar 13, 2024 · 3 comments
Labels
Milestone

Comments

@lindnemi
Copy link
Contributor

Describe the Bug

The baseyear in pypsa-ariadne is 2020. We want to enforce capacities that have been build in 2020 or afterwards.

At the moment this is done in add_existing_baseyear.py, just as if the build year was before 2020, by setting p_nom.
However, after the optimisation, for some carriers, the optimal capacity is smaller than p_nom. This means that the already existing assets are not used by the model. Why?

  1. A constraint for exisiting capacities is added at
    n.generators.loc[already_build, "p_nom_min"] = capacity.loc[
    already_build.str.replace(name_suffix, "")
    ].values

However, for renewable carriers p_nom_min gets reset to 0 in solve_network.py. I would consider this a bug, since that way existing capacities get disregarded. The responsible lines are

gen_i = n.generators[(n.generators.carrier.isin(carriers)) & (ext_i)].index
n.generators.loc[gen_i, "p_nom_min"] = 0
and
extendable_i = (n.generators.carrier == carrier) & n.generators.p_nom_extendable
n.generators.loc[extendable_i, "p_nom_min"] = 0

Apparently the behaviour was first introduced in #728 to limit the land use of renewables.

  1. When i revert this PR the p_nom_lims are correctly carried forward. However, then p_nom_min is still smaller than the p_nom for most carriers, which i understand to be indicative of the existing capacities. And thus, once again p_nom_opt is lower than it should be.

  2. For offwind-ac the situation is actually the opposite and p_nom is smaller than p_nom_min. This might be related to the issue that existing wind capacities get added without a suffix and are thus overlooked

How to Fix

Basically two approaches could work:

  1. set p_nom_min = p_nom

  2. differentiate between enforced assets and optimized assets. then carrier-year would exist twice if build year >= base year.

(and also assign all already existing offwind capacities to offwind-ac and offwind-dc)

I am a bit reluctant to simply go for 1. since it might break other peoples code (??)

@lindnemi
Copy link
Contributor Author

With #967 in place and grouping years [2015,2021] all existing capacities seem to be assigned correctly and do not get overwritten by the optimization. However, for the extendable solar-2020 generator, the p_nom is still very high. I thought it would be 0 if all existing capcities are added as solar-2015 and solar-2021. We might get some double counting in n.statistics.installed_capacity because of that. @p-glaum

@fneum
Copy link
Member

fneum commented May 23, 2024

possibly related to #1016

@fneum
Copy link
Member

fneum commented May 24, 2024

However, for the extendable solar-2020 generator, the p_nom is still very high. I thought it would be 0 if all existing capcities are added as solar-2015 and solar-2021.

This is indeed the same issue as in #1016. Renewable capacities can be added in two ways:

  1. In rule add_electricity in case the following configuration is used:
electricity:
  estimate_renewable_capacities:
    enable: true
  1. In rule add_existing_baseyear for any model in myopic mode.

Option 1 should be used only for electricity-only models and overnight sector-coupled models. Option 2 is used in any case for myopic pathway sector-coupled models. This is quite error-prone, and we should change it soon. Will be tracked via #1016.

So, the problem occurs if you do options 1 and 2 simultaneously, in which case all existing capacities are added to p_nom of the first planning horizon. This looks worse than it is, since p_nom only affects the model if the components are not extendable, which they are not in this case.

With option 1 disabled one gets in "results/test-sector-myopic/prenetworks-brownfield/elec_s_5_lvopt___2020.nc":

n.generators.query("carrier == 'solar'").groupby("build_year")[["p_nom_min", "p_nom"]].sum()
build_year p_nom_min p_nom
2005 0 385
2010 0 2629
2015 0 1621.6
2020 1009.8 0

With option 1 enabled, one gets:

build_year p_nom_min p_nom
2005 0 385
2010 0 2629
2015 0 1621.6
2020 1009.8 5646.4

which is wrong / double-counting -- yet without effect on the optimisation

@fneum fneum closed this as completed May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants