@@ -2573,6 +2573,167 @@ def get_final_energy(
25732573
25742574
25752575def get_emissions (n , region , _energy_totals , industry_demand ):
2576+ def get_constraint_emissions (n , ct ):
2577+ lhs = []
2578+
2579+ for port in [col [3 :] for col in n .links if col .startswith ("bus" )]:
2580+ links = n .links .index [
2581+ (n .links .index .str [:2 ] == ct )
2582+ & (n .links [f"bus{ port } " ] == "co2 atmosphere" )
2583+ & ~ n .links .carrier .str .contains (
2584+ "shipping|aviation"
2585+ ) # first exclude aviation to multiply it with a domestic factor later
2586+ ]
2587+
2588+ if port == "0" :
2589+ efficiency = - 1.0
2590+ elif port == "1" :
2591+ efficiency = n .links .loc [links , "efficiency" ]
2592+ else :
2593+ efficiency = n .links .loc [links , f"efficiency{ port } " ]
2594+
2595+ variables = (
2596+ n .links_t .p0 .loc [:, links ]
2597+ .mul (efficiency )
2598+ .mul (n .snapshot_weightings .generators , axis = 0 )
2599+ .sum ()
2600+ )
2601+ if not variables .empty :
2602+ lhs .append (variables )
2603+
2604+ # Aviation demand
2605+ energy_totals = pd .read_csv (snakemake .input .energy_totals , index_col = [0 , 1 ])
2606+ domestic_aviation = energy_totals .loc [
2607+ (ct , snakemake .params .energy_totals_year ), "total domestic aviation"
2608+ ]
2609+ international_aviation = energy_totals .loc [
2610+ (ct , snakemake .params .energy_totals_year ), "total international aviation"
2611+ ]
2612+ domestic_aviation_factor = domestic_aviation / (
2613+ domestic_aviation + international_aviation
2614+ )
2615+ aviation_links = n .links [
2616+ (n .links .index .str [:2 ] == ct ) & (n .links .carrier == "kerosene for aviation" )
2617+ ]
2618+ lhs .append (
2619+ (
2620+ n .links_t .p0 .loc [:, aviation_links .index ]
2621+ .mul (aviation_links .efficiency2 )
2622+ .mul (n .snapshot_weightings .generators , axis = 0 )
2623+ ).sum ()
2624+ * domestic_aviation_factor
2625+ )
2626+
2627+ # Shipping oil
2628+ domestic_navigation = energy_totals .loc [
2629+ (ct , snakemake .params .energy_totals_year ), "total domestic navigation"
2630+ ]
2631+ international_navigation = energy_totals .loc [
2632+ (ct , snakemake .params .energy_totals_year ), "total international navigation"
2633+ ]
2634+ domestic_navigation_factor = domestic_navigation / (
2635+ domestic_navigation + international_navigation
2636+ )
2637+ shipping_links = n .links [
2638+ (n .links .index .str [:2 ] == ct ) & (n .links .carrier == "shipping oil" )
2639+ ]
2640+ lhs .append (
2641+ (
2642+ n .links_t .p0 .loc [:, shipping_links .index ].mul (
2643+ n .snapshot_weightings .generators , axis = 0
2644+ )
2645+ * shipping_links .efficiency2
2646+ ).sum ()
2647+ * domestic_navigation_factor
2648+ )
2649+
2650+ # Shipping methanol
2651+ shipping_meoh_links = n .links [
2652+ (n .links .index .str [:2 ] == ct ) & (n .links .carrier == "shipping methanol" )
2653+ ]
2654+ lhs .append (
2655+ (
2656+ n .links_t .p0 .loc [:, shipping_meoh_links .index ].mul (
2657+ n .snapshot_weightings .generators , axis = 0
2658+ )
2659+ * shipping_meoh_links .efficiency2
2660+ ).sum ()
2661+ * domestic_navigation_factor
2662+ )
2663+
2664+ # Adding Efuel imports and exports to constraint
2665+ incoming_oil = n .links .index [n .links .index == f"EU renewable oil -> { ct } oil" ]
2666+ outgoing_oil = n .links .index [n .links .index == f"{ ct } renewable oil -> EU oil" ]
2667+
2668+ lhs .append (
2669+ (
2670+ - 1
2671+ * n .links_t .p0 .loc [:, incoming_oil ].mul (
2672+ n .snapshot_weightings .generators , axis = 0
2673+ )
2674+ * 0.2571
2675+ ).sum ()
2676+ )
2677+ lhs .append (
2678+ (
2679+ n .links_t .p0 .loc [:, outgoing_oil ].mul (
2680+ n .snapshot_weightings .generators , axis = 0
2681+ )
2682+ * 0.2571
2683+ ).sum ()
2684+ )
2685+
2686+ incoming_methanol = n .links .index [
2687+ n .links .index == f"EU methanol -> { ct } methanol"
2688+ ]
2689+ outgoing_methanol = n .links .index [
2690+ n .links .index == f"{ ct } methanol -> EU methanol"
2691+ ]
2692+
2693+ lhs .append (
2694+ (
2695+ - 1
2696+ * n .links_t .p0 .loc [:, incoming_methanol ].mul (
2697+ n .snapshot_weightings .generators , axis = 0
2698+ )
2699+ / snakemake .config ["sector" ]["MWh_MeOH_per_tCO2" ]
2700+ ).sum ()
2701+ )
2702+
2703+ lhs .append (
2704+ (
2705+ n .links_t .p0 .loc [:, outgoing_methanol ].mul (
2706+ n .snapshot_weightings .generators , axis = 0
2707+ )
2708+ / snakemake .config ["sector" ]["MWh_MeOH_per_tCO2" ]
2709+ ).sum ()
2710+ )
2711+
2712+ # Methane
2713+ incoming_CH4 = n .links .index [n .links .index == f"EU renewable gas -> { ct } gas" ]
2714+ outgoing_CH4 = n .links .index [n .links .index == f"{ ct } renewable gas -> EU gas" ]
2715+
2716+ lhs .append (
2717+ (
2718+ - 1
2719+ * n .links_t .p0 .loc [:, incoming_CH4 ].mul (
2720+ n .snapshot_weightings .generators , axis = 0
2721+ )
2722+ * 0.198
2723+ ).sum ()
2724+ )
2725+
2726+ lhs .append (
2727+ (
2728+ n .links_t .p0 .loc [:, outgoing_CH4 ].mul (
2729+ n .snapshot_weightings .generators , axis = 0
2730+ )
2731+ * 0.198
2732+ ).sum ()
2733+ )
2734+
2735+ return pd .concat (lhs ).sum () * t2Mt
2736+
25762737 energy_totals = _energy_totals .loc [region [0 :2 ]]
25772738
25782739 industry_DE = industry_demand .filter (
@@ -2587,6 +2748,8 @@ def get_emissions(n, region, _energy_totals, industry_demand):
25872748
25882749 var = pd .Series ()
25892750
2751+ var ["Emissions|CO2|Model|Constraint" ] = get_constraint_emissions (n , region ).sum ()
2752+
25902753 co2_emissions = (
25912754 n .statistics .supply (bus_carrier = "co2" , ** kwargs )
25922755 .filter (like = region )
0 commit comments