From 67ee6cb86e316d62ae66385a3f643986ed8cd7ba Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 6 Jul 2021 18:32:35 +0200 Subject: [PATCH] first step towards agriculture, forestry and fishing --- config.default.yaml | 3 ++ scripts/build_energy_totals.py | 42 ++++++++++++++-- scripts/prepare_sector_network.py | 79 +++++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 9 deletions(-) diff --git a/config.default.yaml b/config.default.yaml index 5f1fa1b8..bb60509a 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -173,6 +173,9 @@ sector: 2050: 0.85 transport_fuel_cell_efficiency: 0.5 transport_internal_combustion_efficiency: 0.3 + agriculture_machinery_electric_share: 0.12 # approximately as today + agriculture_machinery_fuel_efficiency: 0.7 # for conversion of fuel oil to use + agriculture_machinery_electric_efficiency: 0.3 # for conversion of electricity to use shipping_average_efficiency: 0.4 #For conversion of fuel oil to propulsion in 2011 time_dep_hp_cop: true #time dependent heat pump coefficient of performance heat_pump_sink_T: 55. # Celsius, based on DTU / large area radiators; used in build_cop_profiles.py diff --git a/scripts/build_energy_totals.py b/scripts/build_energy_totals.py index aec1c61b..7fdd305a 100644 --- a/scripts/build_energy_totals.py +++ b/scripts/build_energy_totals.py @@ -117,6 +117,7 @@ to_ipcc = { "total energy": "1 - Energy", "industrial processes": "2 - Industrial Processes and Product Use", "agriculture": "3 - Agriculture", + "agriculture, forestry and fishing": '1.A.4.c - Agriculture/Forestry/Fishing', "LULUCF": "4 - Land Use, Land-Use Change and Forestry", "waste management": "5 - Waste management", "other": "6 - Other Sector", @@ -182,7 +183,7 @@ def idees_per_country(ct, year): ct_idees = idees_rename.get(ct, ct) fn_residential = f"{base_dir}/JRC-IDEES-2015_Residential_{ct_idees}.xlsx" - fn_services = f"{base_dir}/JRC-IDEES-2015_Tertiary_{ct_idees}.xlsx" + fn_tertiary = f"{base_dir}/JRC-IDEES-2015_Tertiary_{ct_idees}.xlsx" fn_transport = f"{base_dir}/JRC-IDEES-2015_Transport_{ct_idees}.xlsx" # residential @@ -214,7 +215,7 @@ def idees_per_country(ct, year): # services - df = pd.read_excel(fn_services, "SER_hh_fec", index_col=0)[year] + df = pd.read_excel(fn_tertiary, "SER_hh_fec", index_col=0)[year] ct_totals["total services space"] = df["Space heating"] @@ -231,7 +232,7 @@ def idees_per_country(ct, year): assert df.index[31] == "Electricity" ct_totals["electricity services cooking"] = df[31] - df = pd.read_excel(fn_services, "SER_summary", index_col=0)[year] + df = pd.read_excel(fn_tertiary, "SER_summary", index_col=0)[year] row = "Energy consumption by fuel - Eurostat structure (ktoe)" ct_totals["total services"] = df[row] @@ -239,6 +240,34 @@ def idees_per_country(ct, year): assert df.index[50] == "Electricity" ct_totals["electricity services"] = df[50] + # agriculture, forestry and fishing + + start = "Detailed split of energy consumption (ktoe)" + end = "Market shares of energy uses (%)" + + df = pd.read_excel(fn_tertiary, "AGR_fec", index_col=0).loc[start:end, year] + + rows = [ + "Lighting", + "Ventilation", + "Specific electricity uses", + "Pumping devices (electric)" + ] + ct_totals["total agriculture electricity"] = df[rows].sum() + + rows = ["Specific heat uses", "Low enthalpy heat"] + ct_totals["total agriculture heat"] = df[rows].sum() + + rows = [ + "Motor drives", + "Farming machine drives (diesel oil incl. biofuels)", + "Pumping devices (diesel oil incl. biofuels)", + ] + ct_totals["total agriculture machinery"] = df[rows].sum() + + row = ["Agriculture, forestry and fishing"] + ct_totals["total agriculture"] = df[row] + # transport df = pd.read_excel(fn_transport, "TrRoad_ene", index_col=0)[year] @@ -540,10 +569,13 @@ def build_eea_co2(year=1990): "international aviation", "domestic navigation", "international navigation", + "agriculture, forstry and fishing" ] emissions["industrial non-elec"] = emissions["total energy"] - emissions[to_subtract].sum(axis=1) - to_drop = ["total energy", "total wL", "total woL"] + emissions["agriculture"] += emissions["agriculture, forestry and fishing"] + + to_drop = ["total energy", "total wL", "total woL", "agriculture, forestry and fishing"] emissions.drop(columns=to_drop, inplace=True) # convert from Gg to Mt @@ -588,7 +620,7 @@ def build_co2_totals(countries, eea_co2, eurostat_co2): # does not include industrial process emissions or fuel processing/refining "industrial non-elec": (ct, "+", "Industry"), # does not include non-energy emissions - "agriculture": (ct, "+", "+", "Agriculture / Forestry"), + "agriculture": (eurostat_co2.index.get_level_values(0) == 'NL') & eurostat_co2.index.isin(["Agriculture / Forestry", "Fishing"], level=3), } for i, mi in mappings.items(): diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index fa485e6a..315b9980 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -42,6 +42,10 @@ def emission_sectors_from_opts(opts): "domestic navigation", "international navigation" ] + if "A" in opts: + sectors += [ + "agriulture" + ] return sectors @@ -728,8 +732,9 @@ def insert_electricity_distribution_grid(n, costs): capital_cost=costs.at['electricity distribution grid', 'fixed'] * cost_factor ) - # this catches regular electricity load and "industry electricity" - loads = n.loads.index[n.loads.carrier.str.contains("electricity")] + # this catches regular electricity load and "industry electricity" and + # "agriculture machinery electric" and "agriculture electricity" + loads = n.loads.index[n.loads.carrier.str.contains("electric")] n.loads.loc[loads, "bus"] += " low voltage" bevs = n.links.index[n.links.carrier == "BEV charger"] @@ -1163,8 +1168,8 @@ def add_land_transport(n, costs): co2 = ice_share / ice_efficiency * transport[nodes].sum().sum() / 8760 * costs.at["oil", 'CO2 intensity'] - n.madd("Load", - ["land transport oil emissions"], + n.add("Load", + "land transport oil emissions", bus="co2 atmosphere", carrier="land transport oil emissions", p_set=-co2 @@ -1901,6 +1906,69 @@ def add_waste_heat(n): n.links.loc[urban_central + " H2 Fuel Cell", "efficiency2"] = 0.95 - n.links.loc[urban_central + " H2 Fuel Cell", "efficiency"] +def add_agriculture(n, costs): + + nodes = pop_layout.index + + # electricity + + n.madd("Load", + nodes, + suffix=" agriculture electricity", + bus=nodes, + carrier='agriculture electricity', + p_set=nodal_energy_totals.loc[nodes, "total agriculture electricity"] / 8760 + ) + + # heat + + n.madd("Load", + nodes, + suffix=" agriculture heat", + bus=nodes + " services rural heat", + carrier="agriculture heat", + p_set=nodal_energy_totals.loc[nodes, "total agriculture heat"] / 8760 + ) + + # machinery + + electric_share = get(options["agriculture_machinery_electric_share"], investment_year) + assert electric_share <= 1. + ice_share = 1 - electric_share + + machinery_nodal_energy = nodal_energy_totals.loc[nodes, "total agriculture machinery"] + + if electric_share > 0: + + efficiency_gain = options["agriculture_machinery_fuel_efficiency"] / options["agriculture_machinery_electric_efficiency"] + + n.add("Load", + nodes, + suffix=" agriculture machinery electric", + bus=nodes, + carrier="agriculture machinery electric", + p_set=electric_share * efficiency_gain * machinery_nodal_energy / 8760, + ) + + if ice_share > 0: + + n.add("Load", + "agriculture machinery oil", + bus="EU oil", + carrier="agriculture machinery oil", + p_set=ice_share * machinery_nodal_energy / 8760 + ) + + co2 = ice_share * machinery_nodal_energy / 8760 * costs.at["oil", 'CO2 intensity'] + + n.add("Load", + "agriculture machinery oil emissions", + bus="co2 atmosphere", + carrier="agriculture machinery oil emissions", + p_set=-co2 + ) + + def decentral(n): """Removes the electricity transmission system.""" n.lines.drop(n.lines.index, inplace=True) @@ -2027,6 +2095,9 @@ if __name__ == "__main__": if "I" in opts and "H" in opts: add_waste_heat(n) + if "A" in opts: # requires H and I + add_agriculture(n, costs) + if options['dac']: add_dac(n, costs)