merge master
This commit is contained in:
commit
692f4705c4
@ -21,9 +21,9 @@ it.
|
|||||||
PyPSA-Eur-Sec builds on the electricity generation and transmission
|
PyPSA-Eur-Sec builds on the electricity generation and transmission
|
||||||
model [PyPSA-Eur](https://github.com/PyPSA/pypsa-eur) to add demand
|
model [PyPSA-Eur](https://github.com/PyPSA/pypsa-eur) to add demand
|
||||||
and supply for the following sectors: transport, space and water
|
and supply for the following sectors: transport, space and water
|
||||||
heating, biomass, industry and industrial feedstocks. This completes
|
heating, biomass, industry and industrial feedstocks, agriculture,
|
||||||
the energy system and includes all greenhouse gas emitters except
|
forestry and fishing. This completes the energy system and includes
|
||||||
waste management, agriculture, forestry and land use.
|
all greenhouse gas emitters except waste management and land use.
|
||||||
|
|
||||||
Please see the [documentation](https://pypsa-eur-sec.readthedocs.io/)
|
Please see the [documentation](https://pypsa-eur-sec.readthedocs.io/)
|
||||||
for installation instructions and other useful information about the snakemake workflow.
|
for installation instructions and other useful information about the snakemake workflow.
|
||||||
|
@ -9,7 +9,6 @@ wildcard_constraints:
|
|||||||
lv="[a-z0-9\.]+",
|
lv="[a-z0-9\.]+",
|
||||||
simpl="[a-zA-Z0-9]*",
|
simpl="[a-zA-Z0-9]*",
|
||||||
clusters="[0-9]+m?",
|
clusters="[0-9]+m?",
|
||||||
sectors="[+a-zA-Z0-9]+",
|
|
||||||
opts="[-+a-zA-Z0-9]*",
|
opts="[-+a-zA-Z0-9]*",
|
||||||
sector_opts="[-+a-zA-Z0-9\.\s]*"
|
sector_opts="[-+a-zA-Z0-9\.\s]*"
|
||||||
|
|
||||||
|
@ -21,13 +21,14 @@ scenario:
|
|||||||
opts: # only relevant for PyPSA-Eur
|
opts: # only relevant for PyPSA-Eur
|
||||||
- ''
|
- ''
|
||||||
sector_opts: # this is where the main scenario settings are
|
sector_opts: # this is where the main scenario settings are
|
||||||
- Co2L0-3H-T-H-B-I-solar+p3-dist1
|
- Co2L0-3H-T-H-B-I-A-solar+p3-dist1
|
||||||
# to really understand the options here, look in scripts/prepare_sector_network.py
|
# to really understand the options here, look in scripts/prepare_sector_network.py
|
||||||
# Co2Lx specifies the CO2 target in x% of the 1990 values; default will give default (5%);
|
# Co2Lx specifies the CO2 target in x% of the 1990 values; default will give default (5%);
|
||||||
# Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions
|
# Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions
|
||||||
# xH is the temporal resolution; 3H is 3-hourly, i.e. one snapshot every 3 hours
|
# xH is the temporal resolution; 3H is 3-hourly, i.e. one snapshot every 3 hours
|
||||||
# single letters are sectors: T for land transport, H for building heating,
|
# single letters are sectors: T for land transport, H for building heating,
|
||||||
# B for biomass supply, I for industry, shipping and aviation
|
# B for biomass supply, I for industry, shipping and aviation,
|
||||||
|
# A for agriculture, forestry and fishing
|
||||||
# solar+c0.5 reduces the capital cost of solar to 50\% of reference value
|
# solar+c0.5 reduces the capital cost of solar to 50\% of reference value
|
||||||
# solar+p3 multiplies the available installable potential by factor 3
|
# solar+p3 multiplies the available installable potential by factor 3
|
||||||
# co2 stored+e2 multiplies the potential of CO2 sequestration by a factor 2
|
# co2 stored+e2 multiplies the potential of CO2 sequestration by a factor 2
|
||||||
@ -181,6 +182,9 @@ sector:
|
|||||||
2050: 0.85
|
2050: 0.85
|
||||||
transport_fuel_cell_efficiency: 0.5
|
transport_fuel_cell_efficiency: 0.5
|
||||||
transport_internal_combustion_efficiency: 0.3
|
transport_internal_combustion_efficiency: 0.3
|
||||||
|
agriculture_machinery_electric_share: 0
|
||||||
|
agriculture_machinery_fuel_efficiency: 0.7 # fuel oil per use
|
||||||
|
agriculture_machinery_electric_efficiency: 0.3 # electricity per use
|
||||||
shipping_average_efficiency: 0.4 #For conversion of fuel oil to propulsion in 2011
|
shipping_average_efficiency: 0.4 #For conversion of fuel oil to propulsion in 2011
|
||||||
shipping_hydrogen_liquefaction: false # whether to consider liquefaction costs for shipping H2 demands
|
shipping_hydrogen_liquefaction: false # whether to consider liquefaction costs for shipping H2 demands
|
||||||
shipping_hydrogen_share: # 1 means all hydrogen FC
|
shipping_hydrogen_share: # 1 means all hydrogen FC
|
||||||
@ -477,6 +481,10 @@ plotting:
|
|||||||
CC: k
|
CC: k
|
||||||
co2: '#123456'
|
co2: '#123456'
|
||||||
co2 vent: '#654321'
|
co2 vent: '#654321'
|
||||||
|
agriculture heat: '#D07A7A'
|
||||||
|
agriculture machinery oil: '#1e1e1e'
|
||||||
|
agriculture machinery oil emissions: '#111111'
|
||||||
|
agriculture electricity: '#222222'
|
||||||
solid biomass for industry co2 from atmosphere: '#654321'
|
solid biomass for industry co2 from atmosphere: '#654321'
|
||||||
solid biomass for industry co2 to stored: '#654321'
|
solid biomass for industry co2 to stored: '#654321'
|
||||||
gas for industry co2 to atmosphere: '#654321'
|
gas for industry co2 to atmosphere: '#654321'
|
||||||
|
@ -169,7 +169,7 @@ PyPSA-Eur-Sec 0.6.0 (4 October 2021)
|
|||||||
* Implemented changes to ``n.snapshot_weightings`` in PyPSA v0.18.0.
|
* Implemented changes to ``n.snapshot_weightings`` in PyPSA v0.18.0.
|
||||||
|
|
||||||
* Compatibility with ``xarray`` version 0.19.
|
* Compatibility with ``xarray`` version 0.19.
|
||||||
*
|
|
||||||
* New dependencies: ``tqdm``, ``atlite>=0.2.4``, ``pytz`` and ``geopy`` (optional).
|
* New dependencies: ``tqdm``, ``atlite>=0.2.4``, ``pytz`` and ``geopy`` (optional).
|
||||||
These are included in the environment specifications of PyPSA-Eur v0.3.0.
|
These are included in the environment specifications of PyPSA-Eur v0.3.0.
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ Heat demand is split into:
|
|||||||
|
|
||||||
* ``urban central``: large-scale district heating networks in urban areas with dense heat demand
|
* ``urban central``: large-scale district heating networks in urban areas with dense heat demand
|
||||||
* ``residential/services urban decentral``: heating for individual buildings in urban areas
|
* ``residential/services urban decentral``: heating for individual buildings in urban areas
|
||||||
* ``residential/services rural``: heating for individual buildings in rural areas
|
* ``residential/services rural``: heating for individual buildings in rural areas, agriculture heat uses
|
||||||
|
|
||||||
|
|
||||||
Heat supply
|
Heat supply
|
||||||
@ -189,7 +189,7 @@ Only wastes and residues from the JRC ENSPRESO biomass dataset.
|
|||||||
Oil product demand
|
Oil product demand
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Transport fuels and naphtha as a feedstock for the chemicals industry.
|
Transport fuels, agriculture machinery and naphtha as a feedstock for the chemicals industry.
|
||||||
|
|
||||||
Oil product supply
|
Oil product supply
|
||||||
======================
|
======================
|
||||||
|
@ -117,6 +117,7 @@ to_ipcc = {
|
|||||||
"total energy": "1 - Energy",
|
"total energy": "1 - Energy",
|
||||||
"industrial processes": "2 - Industrial Processes and Product Use",
|
"industrial processes": "2 - Industrial Processes and Product Use",
|
||||||
"agriculture": "3 - Agriculture",
|
"agriculture": "3 - Agriculture",
|
||||||
|
"agriculture, forestry and fishing": '1.A.4.c - Agriculture/Forestry/Fishing',
|
||||||
"LULUCF": "4 - Land Use, Land-Use Change and Forestry",
|
"LULUCF": "4 - Land Use, Land-Use Change and Forestry",
|
||||||
"waste management": "5 - Waste management",
|
"waste management": "5 - Waste management",
|
||||||
"other": "6 - Other Sector",
|
"other": "6 - Other Sector",
|
||||||
@ -182,7 +183,7 @@ def idees_per_country(ct, year):
|
|||||||
|
|
||||||
ct_idees = idees_rename.get(ct, ct)
|
ct_idees = idees_rename.get(ct, ct)
|
||||||
fn_residential = f"{base_dir}/JRC-IDEES-2015_Residential_{ct_idees}.xlsx"
|
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"
|
fn_transport = f"{base_dir}/JRC-IDEES-2015_Transport_{ct_idees}.xlsx"
|
||||||
|
|
||||||
# residential
|
# residential
|
||||||
@ -220,7 +221,7 @@ def idees_per_country(ct, year):
|
|||||||
|
|
||||||
# services
|
# 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"]
|
ct_totals["total services space"] = df["Space heating"]
|
||||||
|
|
||||||
@ -237,7 +238,7 @@ def idees_per_country(ct, year):
|
|||||||
assert df.index[31] == "Electricity"
|
assert df.index[31] == "Electricity"
|
||||||
ct_totals["electricity services cooking"] = df[31]
|
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)"
|
row = "Energy consumption by fuel - Eurostat structure (ktoe)"
|
||||||
ct_totals["total services"] = df[row]
|
ct_totals["total services"] = df[row]
|
||||||
@ -251,6 +252,35 @@ def idees_per_country(ct, year):
|
|||||||
assert df.index[53] == 'Thermal uses'
|
assert df.index[53] == 'Thermal uses'
|
||||||
ct_totals["thermal uses services"] = df[53]
|
ct_totals["thermal uses services"] = df[53]
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
# transport
|
||||||
|
|
||||||
df = pd.read_excel(fn_transport, "TrRoad_ene", index_col=0)[year]
|
df = pd.read_excel(fn_transport, "TrRoad_ene", index_col=0)[year]
|
||||||
@ -568,10 +598,13 @@ def build_eea_co2(year=1990):
|
|||||||
"international aviation",
|
"international aviation",
|
||||||
"domestic navigation",
|
"domestic navigation",
|
||||||
"international navigation",
|
"international navigation",
|
||||||
|
"agriculture, forestry and fishing"
|
||||||
]
|
]
|
||||||
emissions["industrial non-elec"] = emissions["total energy"] - emissions[to_subtract].sum(axis=1)
|
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)
|
emissions.drop(columns=to_drop, inplace=True)
|
||||||
|
|
||||||
# convert from Gg to Mt
|
# convert from Gg to Mt
|
||||||
@ -616,7 +649,7 @@ def build_co2_totals(countries, eea_co2, eurostat_co2):
|
|||||||
# does not include industrial process emissions or fuel processing/refining
|
# does not include industrial process emissions or fuel processing/refining
|
||||||
"industrial non-elec": (ct, "+", "Industry"),
|
"industrial non-elec": (ct, "+", "Industry"),
|
||||||
# does not include non-energy emissions
|
# does not include non-energy emissions
|
||||||
"agriculture": (ct, "+", "+", "Agriculture / Forestry"),
|
"agriculture": (eurostat_co2.index.get_level_values(0) == ct) & eurostat_co2.index.isin(["Agriculture / Forestry", "Fishing"], level=3),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, mi in mappings.items():
|
for i, mi in mappings.items():
|
||||||
|
@ -92,6 +92,10 @@ def emission_sectors_from_opts(opts):
|
|||||||
"domestic navigation",
|
"domestic navigation",
|
||||||
"international navigation"
|
"international navigation"
|
||||||
]
|
]
|
||||||
|
if "A" in opts:
|
||||||
|
sectors += [
|
||||||
|
"agriculture"
|
||||||
|
]
|
||||||
|
|
||||||
return sectors
|
return sectors
|
||||||
|
|
||||||
@ -882,8 +886,9 @@ def insert_electricity_distribution_grid(n, costs):
|
|||||||
capital_cost=costs.at['electricity distribution grid', 'fixed'] * cost_factor
|
capital_cost=costs.at['electricity distribution grid', 'fixed'] * cost_factor
|
||||||
)
|
)
|
||||||
|
|
||||||
# this catches regular electricity load and "industry electricity"
|
# this catches regular electricity load and "industry electricity" and
|
||||||
loads = n.loads.index[n.loads.carrier.str.contains("electricity")]
|
# "agriculture machinery electric" and "agriculture electricity"
|
||||||
|
loads = n.loads.index[n.loads.carrier.str.contains("electric")]
|
||||||
n.loads.loc[loads, "bus"] += " low voltage"
|
n.loads.loc[loads, "bus"] += " low voltage"
|
||||||
|
|
||||||
bevs = n.links.index[n.links.carrier == "BEV charger"]
|
bevs = n.links.index[n.links.carrier == "BEV charger"]
|
||||||
@ -1321,8 +1326,8 @@ def add_land_transport(n, costs):
|
|||||||
|
|
||||||
co2 = ice_share / ice_efficiency * transport[nodes].sum().sum() / 8760 * costs.at["oil", 'CO2 intensity']
|
co2 = ice_share / ice_efficiency * transport[nodes].sum().sum() / 8760 * costs.at["oil", 'CO2 intensity']
|
||||||
|
|
||||||
n.madd("Load",
|
n.add("Load",
|
||||||
["land transport oil emissions"],
|
"land transport oil emissions",
|
||||||
bus="co2 atmosphere",
|
bus="co2 atmosphere",
|
||||||
carrier="land transport oil emissions",
|
carrier="land transport oil emissions",
|
||||||
p_set=-co2
|
p_set=-co2
|
||||||
@ -2161,6 +2166,71 @@ 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"]
|
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):
|
||||||
|
|
||||||
|
logger.info('Add agriculture, forestry and fishing sector.')
|
||||||
|
|
||||||
|
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"] * 1e6 / 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"] * 1e6 / 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.madd("Load",
|
||||||
|
nodes,
|
||||||
|
suffix=" agriculture machinery electric",
|
||||||
|
bus=nodes,
|
||||||
|
carrier="agriculture machinery electric",
|
||||||
|
p_set=electric_share / efficiency_gain * machinery_nodal_energy * 1e6 / 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.sum() * 1e6 / 8760
|
||||||
|
)
|
||||||
|
|
||||||
|
co2 = ice_share * machinery_nodal_energy.sum() * 1e6 / 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):
|
def decentral(n):
|
||||||
"""Removes the electricity transmission system."""
|
"""Removes the electricity transmission system."""
|
||||||
n.lines.drop(n.lines.index, inplace=True)
|
n.lines.drop(n.lines.index, inplace=True)
|
||||||
@ -2297,6 +2367,9 @@ if __name__ == "__main__":
|
|||||||
if "I" in opts and "H" in opts:
|
if "I" in opts and "H" in opts:
|
||||||
add_waste_heat(n)
|
add_waste_heat(n)
|
||||||
|
|
||||||
|
if "A" in opts: # requires H and I
|
||||||
|
add_agriculture(n, costs)
|
||||||
|
|
||||||
if options['dac']:
|
if options['dac']:
|
||||||
add_dac(n, costs)
|
add_dac(n, costs)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user