PyPSA / pypsa-ariadne

High resolution, sector-coupled model of the German Energy System
https://ariadneprojekt.de/en/model-documentation-pypsa/
MIT License
6 stars 4 forks source link

non-CO2 GHG correction for national CO2 targets #5

Closed lindnemi closed 5 months ago

lindnemi commented 5 months ago

The Nationale Emissionsminderungsziele contain all Kyoto gases, Pypsa-eur models only CO2.

We take the non-CO2 Kyoto gases from the ariadne database, and subtract them from the targets. Interestingly this would lead to negative CO2 emissions targets for 2050 -> Does that make sense?

I did not consider any negative emissions from Land Use, Land Use Change and Afforestation yet (as these are not in the Ariadne database). However the KSG mentions negative sector targets for LULUCF. How should these be included? @nworbmot

This is the script i used to compute the adjusted CO2 targets.

import pyam
import numpy as np
import pandas as pd

pyam.iiasa.set_config(USERNAME, PASSWORD)

model_raw = pyam.read_iiasa("ariadne_intern",
                            model="Hybrid",
                            scenario="8Gt_EnSec")

model_df = model_raw.timeseries()

df = model_df.loc["Hybrid","8Gt_EnSec","Deutschland"]

target_years = [2020,2025,2030,2035,2040,2045,2050]

nonCO2Mt = df.loc["Emissions|Kyoto Gases","Mt CO2-equiv/yr"][target_years] - df.loc["Emissions|CO2 incl Bunkers","Mt CO2/yr"][target_years]

baseline1990 = 1251 # in Mt CO2-equiv
initial_years2025 = np.array([813, 643])
later_years = (1 - np.array([0.65, 0.77, 0.88, 1.0, 1.0])) * baseline1990

targetsMt = pd.Series(
    index=target_years, 
    data=np.append(initial_years2025 , later_years)
)

((targetsMt - nonCO2Mt) / baseline1990).round(2)
lindnemi commented 5 months ago

Sources are:

https://www.umweltbundesamt.de/daten/klima/treibhausgasminderungsziele-deutschlands#nationale-treibhausgasminderungsziele-und-deren-umsetzung https://dserver.bundestag.de/btd/20/082/2008290.pdf https://www.gesetze-im-internet.de/ksg/BJNR251310019.html#BJNR251310019BJNG000200000

nworbmot commented 5 months ago

Let's check with PIK about LULUCF, since it should be included in the target. I'll ask!

lindnemi commented 5 months ago

Updated the script for computing the emissions


# The Pypsa baseline disregards other GHG and LULUCF

ghg_pypsa = ghg_ksg = (
    df.loc["Emissions|Kyoto Gases","Mt CO2-equiv/yr"]
    - df.loc["Emissions|Kyoto Gases|Land-Use Change","Mt CO2-equiv/yr"]
)                    

co2_pypsa = (
    df.loc["Emissions|CO2 incl Bunkers","Mt CO2/yr"]  
    - df.loc["Emissions|CO2|Land-Use Change","Mt CO2-equiv/yr"] 
)

co2_ksg = co2_pypsa - df.loc["Emissions|CO2|Energy|Demand|Bunkers","Mt CO2/yr"]

nonco2 = ghg_ksg - co2_ksg
baseline_ksg = 1251
baseline_pypsa = 1052

# GHG target according to KSG
initial_years2030_ksg = np.array([813, 643, 438])
later_years_ksg = (1 - np.array([0.77, 0.88, 1.0, 1.0])) * baseline_ksg
targets_ksg = pd.Series(
    index=target_years, 
    data=np.append(initial_years2030_ksg , later_years_ksg)
)

# CO2 only targets according to KSG and REMIND
(targets_ksg - nonco2)[target_years]

# Since PyPSA includes bunkers they have to be added to the targets
targets_pypsa =  (targets_ksg - nonco2 + df.loc["Emissions|CO2|Energy|Demand|Bunkers","Mt CO2/yr"])

# Targets have to be formulated as a fraction of the baseline emissions that pypsa uses
(targets_pypsa[target_years] / baseline_pypsa).round(2)

This gives:

2020    0.73
2025    0.57
2030    0.40
2035    0.26
2040    0.12
2045   -0.03
2050   -0.02