Merge branch 'master' into jrc-idees-2020

This commit is contained in:
lisazeyen 2024-08-07 11:58:22 +02:00 committed by GitHub
commit 95903eeca7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 413 additions and 200 deletions

View File

@ -65,10 +65,10 @@ The dataset consists of:
(alternating current lines at and above 220kV voltage level and all high
voltage direct current lines) and 3803 substations.
- The open power plant database
[powerplantmatching](https://github.com/FRESNA/powerplantmatching).
[powerplantmatching](https://github.com/PyPSA/powerplantmatching).
- Electrical demand time series from the
[OPSD project](https://open-power-system-data.org/).
- Renewable time series based on ERA5 and SARAH, assembled using the [atlite tool](https://github.com/FRESNA/atlite).
- Renewable time series based on ERA5 and SARAH, assembled using the [atlite tool](https://github.com/PyPSA/atlite).
- Geographical potentials for wind and solar generators based on land use (CORINE) and excluding nature reserves (Natura2000) are computed with the [atlite library](https://github.com/PyPSA/atlite).
A sector-coupled extension adds demand

View File

@ -355,7 +355,6 @@ biomass:
- Secondary Forestry residues - woodchips
- Sawdust
- Residues from landscape care
- Municipal waste
not included:
- Sugar from sugar beet
- Rape seed
@ -369,6 +368,8 @@ biomass:
biogas:
- Manure solid, liquid
- Sludge
municipal solid waste:
- Municipal waste
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#solar-thermal
solar_thermal:
@ -397,6 +398,7 @@ sector:
biomass: true
industry: true
agriculture: true
fossil_fuels: true
district_heating:
potential: 0.6
progress:
@ -596,7 +598,9 @@ sector:
conventional_generation:
OCGT: gas
biomass_to_liquid: false
electrobiofuels: false
biosng: false
municipal_solid_waste: false
limit_max_growth:
enable: false
# allowing 30% larger than max historic growth
@ -618,6 +622,12 @@ sector:
max_boost: 0.25
var_cf: true
sustainability_factor: 0.0025
solid_biomass_import:
enable: false
price: 54 #EUR/MWh
max_amount: 1390 # TWh
upstream_emissions_factor: .1 #share of solid biomass CO2 emissions at full combustion
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#industry
industry:
@ -1015,6 +1025,8 @@ plotting:
biogas: '#e3d37d'
biomass: '#baa741'
solid biomass: '#baa741'
municipal solid waste: '#91ba41'
solid biomass import: '#d5ca8d'
solid biomass transport: '#baa741'
solid biomass for industry: '#7a6d26'
solid biomass for industry CC: '#47411c'
@ -1028,6 +1040,7 @@ plotting:
services rural biomass boiler: '#c6cf98'
services urban decentral biomass boiler: '#dde5b5'
biomass to liquid: '#32CD32'
electrobiofuels: 'red'
BioSNG: '#123456'
# power transmission
lines: '#6c9459'

View File

@ -23,7 +23,7 @@ Visby-Nas,Sweden - Nas 57°0558″N 18°1427″E / 57.09944°N 18.24
SwePol,Poland - Wierzbięcin 54°308″N 16°5328″E / 54.50222°N 16.89111°E,Sweden - Stärnö 56°911″N 14°5029″E / 56.15306°N 14.84139°E,245(245/0),450,600.0,2000,Thyr,Supplier: ABB,[38],16.891111111111112,54.50222222222222,14.841388888888888,56.153055555555554
Tjæreborg,Denmark - Tjæreborg/Enge 55°2652″N 8°3534″E / 55.44778°N 8.59278°E,Denmark - Tjæreborg/Substation 55°2807″N 8°3336″E / 55.46861°N 8.56000°E,4.3(4.3/0),9,7.0,2000,IGBT,Interconnection to wind power generating stations,,8.592777777777778,55.44777777777778,8.56,55.46861111111111
Italy-Greece,Greece - Arachthos 39°1100″N 20°5748″E / 39.18333°N 20.96333°E,Italy - Galatina 40°953″N 18°749″E / 40.16472°N 18.13028°E,310(200/110),400,500.0,2001,Thyr,,,20.963333333333335,39.18333333333333,18.130277777777778,40.164722222222224
Moyle,UK - Auchencrosh 55°0410″N 4°5850″W / 55.06944°N 4.98056°W,UK - N. Ireland- Ballycronan More 54°5034″N 5°4611″W / 54.84278°N 5.76972°W,63.5(63.5/0),250,2501.0,2001,Thyr,"Supplier: Siemens- Nexans",[39],-4.980555555555556,55.06944444444444,-5.769722222222223,54.842777777777776
Moyle,UK - Auchencrosh 55°0410″N 4°5850″W / 55.06944°N 4.98056°W,UK - N. Ireland- Ballycronan More 54°5034″N 5°4611″W / 54.84278°N 5.76972°W,63.5(63.5/0),250,500.0,2001,Thyr,"Supplier: Siemens- Nexans",[39],-4.980555555555556,55.06944444444444,-5.769722222222223,54.842777777777776
HVDC Troll,Norway - Kollsnes 60°3301″N 4°5026″E / 60.55028°N 4.84056°E,Norway - Offshore platform Troll A 60°4000″N 3°4000″E / 60.66667°N 3.66667°E,70(70/0),60,80.0,2004,IGBT,Power supply for offshore gas compressor Supplier: ABB,[40],4.8405555555555555,60.55027777777778,3.6666666666666665,60.666666666666664
Estlink,Finland - Espoo 60°1214″N 24°3306″E / 60.20389°N 24.55167°E,Estonia - Harku 59°235″N 24°3337″E / 59.38472°N 24.56028°E,105(105/0),150,350.0,2006,IGBT,Supplier: ABB,[40],24.551666666666666,60.20388888888889,24.560277777777777,59.38472222222222
NorNed,Netherlands - Eemshaven 53°264″N 6°5157″E / 53.43444°N 6.86583°E,Norway - Feda 58°1658″N 6°5155″E / 58.28278°N 6.86528°E,580(580/0),450,700.0,2008,Thyr,"Supplier: ABB- Nexans",[40],6.865833333333334,53.434444444444445,6.865277777777778,58.28277777777778

1 Name Converterstation 1 Converterstation 2 Total Length (Cable/Pole) (km) Volt (kV) Power (MW) Year Type Remarks Ref x1 y1 x2 y2
23 SwePol Poland - Wierzbięcin 54°30′8″N 16°53′28″E / 54.50222°N 16.89111°E Sweden - Stärnö 56°9′11″N 14°50′29″E / 56.15306°N 14.84139°E 245(245/0) 450 600.0 2000 Thyr Supplier: ABB [38] 16.891111111111112 54.50222222222222 14.841388888888888 56.153055555555554
24 Tjæreborg Denmark - Tjæreborg/Enge 55°26′52″N 8°35′34″E / 55.44778°N 8.59278°E Denmark - Tjæreborg/Substation 55°28′07″N 8°33′36″E / 55.46861°N 8.56000°E 4.3(4.3/0) 9 7.0 2000 IGBT Interconnection to wind power generating stations 8.592777777777778 55.44777777777778 8.56 55.46861111111111
25 Italy-Greece Greece - Arachthos 39°11′00″N 20°57′48″E / 39.18333°N 20.96333°E Italy - Galatina 40°9′53″N 18°7′49″E / 40.16472°N 18.13028°E 310(200/110) 400 500.0 2001 Thyr 20.963333333333335 39.18333333333333 18.130277777777778 40.164722222222224
26 Moyle UK - Auchencrosh 55°04′10″N 4°58′50″W / 55.06944°N 4.98056°W UK - N. Ireland- Ballycronan More 54°50′34″N 5°46′11″W / 54.84278°N 5.76972°W 63.5(63.5/0) 250 2501.0 500.0 2001 Thyr Supplier: Siemens- Nexans [39] -4.980555555555556 55.06944444444444 -5.769722222222223 54.842777777777776
27 HVDC Troll Norway - Kollsnes 60°33′01″N 4°50′26″E / 60.55028°N 4.84056°E Norway - Offshore platform Troll A 60°40′00″N 3°40′00″E / 60.66667°N 3.66667°E 70(70/0) 60 80.0 2004 IGBT Power supply for offshore gas compressor Supplier: ABB [40] 4.8405555555555555 60.55027777777778 3.6666666666666665 60.666666666666664
28 Estlink Finland - Espoo 60°12′14″N 24°33′06″E / 60.20389°N 24.55167°E Estonia - Harku 59°23′5″N 24°33′37″E / 59.38472°N 24.56028°E 105(105/0) 150 350.0 2006 IGBT Supplier: ABB [40] 24.551666666666666 60.20388888888889 24.560277777777777 59.38472222222222
29 NorNed Netherlands - Eemshaven 53°26′4″N 6°51′57″E / 53.43444°N 6.86583°E Norway - Feda 58°16′58″N 6°51′55″E / 58.28278°N 6.86528°E 580(580/0) 450 700.0 2008 Thyr Supplier: ABB- Nexans [40] 6.865833333333334 53.434444444444445 6.865277777777778 58.28277777777778

View File

@ -341,4 +341,6 @@ texinfo_documents = [
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {"https://docs.python.org/": None}
intersphinx_mapping = {
'https://docs.python.org/': ('https://docs.python.org/3', None),
}

View File

@ -4,8 +4,9 @@ heating,--,"{true, false}",Flag to include heating sector.
biomass,--,"{true, false}",Flag to include biomass sector.
industry,--,"{true, false}",Flag to include industry sector.
agriculture,--,"{true, false}",Flag to include agriculture sector.
fossil_fuels,--,"{true, false}","Flag to include imports of fossil fuels ( [""coal"", ""gas"", ""oil"", ""lignite""])"
district_heating,--,,`prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_
-- potential,--,float,maximum fraction of urban demand which can be supplied by district heating. Ignored where below current fraction.
-- potential,--,float,maximum fraction of urban demand which can be supplied by district heating
-- progress,--,Dictionary with planning horizons as keys., Increase of today's district heating demand to potential maximum district heating share. Progress = 0 means today's district heating share. Progress = 1 means maximum fraction of urban demand is supplied by district heating
-- district_heating_loss,--,float,Share increase in district heat demand in urban central due to heat losses
cluster_heat_buses,--,"{true, false}",Cluster residential and service heat buses in `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_ to one to save memory.
@ -71,7 +72,7 @@ boilers,--,"{true, false}",Add option for transforming gas into heat using gas b
resistive_heaters,--,"{true, false}",Add option for transforming electricity into heat using resistive heaters (independently from gas boilers)
oil_boilers,--,"{true, false}",Add option for transforming oil into heat using boilers
biomass_boiler,--,"{true, false}",Add option for transforming biomass into heat using boilers
overdimension_individual_heating,--,"float",Add option for overdimensioning individual heating systems by a certain factor. This allows them to cover heat demand peaks e.g. 10% higher than those in the data with a setting of 1.1.
overdimension_individual_heating,--,float,Add option for overdimensioning individual heating systems by a certain factor. This allows them to cover heat demand peaks e.g. 10% higher than those in the data with a setting of 1.1.
chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP)
micro_chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP) for decentral areas.
solar_thermal,--,"{true, false}",Add option for using solar thermal to generate heat.
@ -138,6 +139,7 @@ biogas_upgrading_cc,--,"{true, false}",Add option to capture CO2 from biomass up
conventional_generation,,,Add a more detailed description of conventional carriers. Any power generation requires the consumption of fuel from nodes representing that fuel.
biomass_to_liquid,--,"{true, false}",Add option for transforming solid biomass into liquid fuel with the same properties as oil
biosng,--,"{true, false}",Add option for transforming solid biomass into synthesis gas with the same properties as natural gas
municipal_solid_waste,--,"{true, false}",Add option for municipal solid waste
limit_max_growth,,,
-- enable,--,"{true, false}",Add option to limit the maximum growth of a carrier
-- factor,p.u.,float,The maximum growth factor of a carrier (e.g. 1.3 allows 30% larger than max historic growth)
@ -153,3 +155,8 @@ enhanced_geothermal,,,
-- max_boost,--,float,The maximum boost in power output under flexible operation
-- var_cf,--,"{true, false}",Add option for variable capacity factor (see Ricks et al. 2024)
-- sustainability_factor,--,float,Share of sourced heat that is replenished by the earth's core (see details in `build_egs_potentials.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/build_egs_potentials.py>`_)
solid_biomass_import,,,
-- enable,--,"{true, false}",Add option to include solid biomass imports
-- price,currency/MWh,float,Price for importing solid biomass
-- max_amount,Twh,float,Maximum solid biomass import potential
-- upstream_emissions_factor,p.u.,float,Upstream emissions of solid biomass imports

1 Unit Values Description
4 biomass -- {true, false} Flag to include biomass sector.
5 industry -- {true, false} Flag to include industry sector.
6 agriculture -- {true, false} Flag to include agriculture sector.
7 fossil_fuels -- {true, false} Flag to include imports of fossil fuels ( ["coal", "gas", "oil", "lignite"])
8 district_heating -- `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_
9 -- potential -- float maximum fraction of urban demand which can be supplied by district heating. Ignored where below current fraction. maximum fraction of urban demand which can be supplied by district heating
10 -- progress -- Dictionary with planning horizons as keys. Increase of today's district heating demand to potential maximum district heating share. Progress = 0 means today's district heating share. Progress = 1 means maximum fraction of urban demand is supplied by district heating
11 -- district_heating_loss -- float Share increase in district heat demand in urban central due to heat losses
12 cluster_heat_buses -- {true, false} Cluster residential and service heat buses in `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_ to one to save memory.
72 resistive_heaters -- {true, false} Add option for transforming electricity into heat using resistive heaters (independently from gas boilers)
73 oil_boilers -- {true, false} Add option for transforming oil into heat using boilers
74 biomass_boiler -- {true, false} Add option for transforming biomass into heat using boilers
75 overdimension_individual_heating -- float Add option for overdimensioning individual heating systems by a certain factor. This allows them to cover heat demand peaks e.g. 10% higher than those in the data with a setting of 1.1.
76 chp -- {true, false} Add option for using Combined Heat and Power (CHP)
77 micro_chp -- {true, false} Add option for using Combined Heat and Power (CHP) for decentral areas.
78 solar_thermal -- {true, false} Add option for using solar thermal to generate heat.
139 conventional_generation Add a more detailed description of conventional carriers. Any power generation requires the consumption of fuel from nodes representing that fuel.
140 biomass_to_liquid -- {true, false} Add option for transforming solid biomass into liquid fuel with the same properties as oil
141 biosng -- {true, false} Add option for transforming solid biomass into synthesis gas with the same properties as natural gas
142 municipal_solid_waste -- {true, false} Add option for municipal solid waste
143 limit_max_growth
144 -- enable -- {true, false} Add option to limit the maximum growth of a carrier
145 -- factor p.u. float The maximum growth factor of a carrier (e.g. 1.3 allows 30% larger than max historic growth)
155 -- max_boost -- float The maximum boost in power output under flexible operation
156 -- var_cf -- {true, false} Add option for variable capacity factor (see Ricks et al. 2024)
157 -- sustainability_factor -- float Share of sourced heat that is replenished by the earth's core (see details in `build_egs_potentials.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/build_egs_potentials.py>`_)
158 solid_biomass_import
159 -- enable -- {true, false} Add option to include solid biomass imports
160 -- price currency/MWh float Price for importing solid biomass
161 -- max_amount Twh float Maximum solid biomass import potential
162 -- upstream_emissions_factor p.u. float Upstream emissions of solid biomass imports

View File

@ -242,7 +242,7 @@ Rule overview
file
<https://pypsa-eur.readthedocs.io/en/latest/preparation/build_powerplants.html?highlight=powerplants>`__
generated by pypsa-eur which, in turn, is based on the `powerplantmatching
<https://github.com/FRESNA/powerplantmatching>`__ database.
<https://github.com/PyPSA/powerplantmatching>`__ database.
Existing wind and solar capacities are retrieved from `IRENA annual statistics
<https://www.irena.org/Statistics/Download-Data>`__ and distributed among the

View File

@ -25,7 +25,7 @@ With these and the externally extracted ENTSO-E online map topology
Then the process continues by calculating conventional power plant capacities, potentials, and per-unit availability time series for variable renewable energy carriers and hydro power plants with the following rules:
- :mod:`build_powerplants` for today's thermal power plant capacities using `powerplantmatching <https://github.com/FRESNA/powerplantmatching>`__ allocating these to the closest substation for each powerplant,
- :mod:`build_powerplants` for today's thermal power plant capacities using `powerplantmatching <https://github.com/PyPSA/powerplantmatching>`__ allocating these to the closest substation for each powerplant,
- :mod:`build_ship_raster` for building shipping traffic density,
- :mod:`build_renewable_profiles` for the hourly capacity factors and installation potentials constrained by land-use in each substation's Voronoi cell for PV, onshore and offshore wind, and
- :mod:`build_hydro_profile` for the hourly per-unit hydro power availability time series.

View File

@ -19,6 +19,14 @@ Upcoming Release
* Add flag ``sector: fossil_fuels`` in config to remove the option of importing fossil fuels
* split solid biomass potentials into solid biomass and municipal solid waste. Add option to use municipal solid waste. This option is only activated in combination with the flag ``waste_to_energy``
* Add option to import solid biomass
* Add option to produce electrobiofuels (flag ``electrobiofuels``) from solid biomass and hydrogen, as a combination of BtL and Fischer-Tropsch to make more use of the biogenic carbon
* Add flag ``sector: fossil_fuels`` in config to remove the option of importing fossil fuels
* Renamed the carrier of batteries in BEVs from `battery storage` to `EV battery` and the corresponding bus carrier from `Li ion` to `EV battery`. This is to avoid confusion with stationary battery storage.
* Changed default assumptions about waste heat usage from PtX and fuel cells in district heating.

View File

@ -52,6 +52,8 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_databundle",
log:
"logs/retrieve_eurostat_data.log",
retries: 2
conda:
"../envs/retrieve.yaml"
script:
"../scripts/retrieve_eurostat_data.py"
@ -70,6 +72,8 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_databundle",
log:
"logs/retrieve_eurostat_household_data.log",
retries: 2
conda:
"../envs/retrieve.yaml"
script:
"../scripts/retrieve_eurostat_household_data.py"

View File

@ -808,7 +808,7 @@ def voronoi(points, outline, crs=4326):
voronoi = gpd.GeoDataFrame(geometry=voronoi)
joined = gpd.sjoin_nearest(pts, voronoi, how="right")
return joined.dissolve(by="Bus").squeeze()
return joined.dissolve(by="Bus").reindex(points.index).squeeze()
def build_bus_shapes(n, country_shapes, offshore_shapes, countries):

View File

@ -6,7 +6,7 @@
# coding: utf-8
"""
Retrieves conventional powerplant capacities and locations from
`powerplantmatching <https://github.com/FRESNA/powerplantmatching>`_, assigns
`powerplantmatching <https://github.com/PyPSA/powerplantmatching>`_, assigns
these to buses and creates a ``.csv`` file. It is possible to amend the
powerplant database with custom entries provided in
``data/custom_powerplants.csv``.
@ -30,17 +30,17 @@ Inputs
------
- ``networks/base.nc``: confer :ref:`base`.
- ``data/custom_powerplants.csv``: custom powerplants in the same format as `powerplantmatching <https://github.com/FRESNA/powerplantmatching>`_ provides
- ``data/custom_powerplants.csv``: custom powerplants in the same format as `powerplantmatching <https://github.com/PyPSA/powerplantmatching>`_ provides
Outputs
-------
- ``resource/powerplants.csv``: A list of conventional power plants (i.e. neither wind nor solar) with fields for name, fuel type, technology, country, capacity in MW, duration, commissioning year, retrofit year, latitude, longitude, and dam information as documented in the `powerplantmatching README <https://github.com/FRESNA/powerplantmatching/blob/master/README.md>`_; additionally it includes information on the closest substation/bus in ``networks/base.nc``.
- ``resource/powerplants.csv``: A list of conventional power plants (i.e. neither wind nor solar) with fields for name, fuel type, technology, country, capacity in MW, duration, commissioning year, retrofit year, latitude, longitude, and dam information as documented in the `powerplantmatching README <https://github.com/PyPSA/powerplantmatching/blob/master/README.md>`_; additionally it includes information on the closest substation/bus in ``networks/base.nc``.
.. image:: img/powerplantmatching.png
:scale: 30 %
**Source:** `powerplantmatching on GitHub <https://github.com/FRESNA/powerplantmatching>`_
**Source:** `powerplantmatching on GitHub <https://github.com/PyPSA/powerplantmatching>`_
Description
-----------

View File

@ -56,19 +56,25 @@ def define_spatial(nodes, options):
# biomass
spatial.biomass = SimpleNamespace()
spatial.msw = SimpleNamespace()
if options.get("biomass_spatial", options["biomass_transport"]):
spatial.biomass.nodes = nodes + " solid biomass"
spatial.biomass.locations = nodes
spatial.biomass.industry = nodes + " solid biomass for industry"
spatial.biomass.industry_cc = nodes + " solid biomass for industry CC"
spatial.msw.nodes = nodes + " municipal solid waste"
spatial.msw.locations = nodes
else:
spatial.biomass.nodes = ["EU solid biomass"]
spatial.biomass.locations = ["EU"]
spatial.biomass.industry = ["solid biomass for industry"]
spatial.biomass.industry_cc = ["solid biomass for industry CC"]
spatial.msw.nodes = ["EU municipal solid waste"]
spatial.msw.locations = ["EU"]
spatial.biomass.df = pd.DataFrame(vars(spatial.biomass), index=nodes)
spatial.msw.df = pd.DataFrame(vars(spatial.msw), index=nodes)
# co2
@ -542,6 +548,9 @@ def add_carrier_buses(n, carrier, nodes=None):
capital_cost=capital_cost,
)
fossils = ["coal", "gas", "oil", "lignite"]
if options.get("fossil_fuels", True) and carrier in fossils:
n.madd(
"Generator",
nodes,
@ -2246,12 +2255,54 @@ def add_biomass(n, costs):
solid_biomass_potentials_spatial = biomass_potentials["solid biomass"].rename(
index=lambda x: x + " solid biomass"
)
msw_biomass_potentials_spatial = biomass_potentials[
"municipal solid waste"
].rename(index=lambda x: x + " municipal solid waste")
else:
solid_biomass_potentials_spatial = biomass_potentials["solid biomass"].sum()
msw_biomass_potentials_spatial = biomass_potentials[
"municipal solid waste"
].sum()
n.add("Carrier", "biogas")
n.add("Carrier", "solid biomass")
if (
options["municipal_solid_waste"]
and not options["industry"]
and cf_industry["waste_to_energy"]
or cf_industry["waste_to_energy_cc"]
):
logger.warning(
"Flag municipal_solid_waste can be only used with industry "
"sector waste to energy."
"Setting municipal_solid_waste=False."
)
options["municipal_solid_waste"] = False
if options["municipal_solid_waste"]:
n.add("Carrier", "municipal solid waste")
n.madd(
"Bus",
spatial.msw.nodes,
location=spatial.msw.locations,
carrier="municipal solid waste",
)
e_max_pu = pd.Series([1] * (len(n.snapshots) - 1) + [0], index=n.snapshots)
n.madd(
"Store",
spatial.msw.nodes,
bus=spatial.msw.nodes,
carrier="municipal solid waste",
e_nom=msw_biomass_potentials_spatial,
marginal_cost=0, # costs.at["municipal solid waste", "fuel"],
e_max_pu=e_max_pu,
e_initial=msw_biomass_potentials_spatial,
)
n.madd(
"Bus",
spatial.gas.biogas,
@ -2288,6 +2339,54 @@ def add_biomass(n, costs):
e_initial=solid_biomass_potentials_spatial,
)
if options["solid_biomass_import"].get("enable", False):
biomass_import_price = options["solid_biomass_import"]["price"]
# convert TWh in MWh
biomass_import_max_amount = options["solid_biomass_import"]["max_amount"] * 1e6
biomass_import_upstream_emissions = options["solid_biomass_import"][
"upstream_emissions_factor"
]
logger.info(
"Adding biomass import with cost %.2f EUR/MWh, a limit of %.2f TWh, and embedded emissions of %.2f%%",
biomass_import_price,
options["solid_biomass_import"]["max_amount"],
biomass_import_upstream_emissions * 100,
)
n.add("Carrier", "solid biomass import")
n.madd(
"Bus",
["EU solid biomass import"],
location="EU",
carrier="solid biomass import",
)
n.madd(
"Store",
["solid biomass import"],
bus=["EU solid biomass import"],
carrier="solid biomass import",
e_nom=biomass_import_max_amount,
marginal_cost=biomass_import_price,
e_initial=biomass_import_max_amount,
)
n.madd(
"Link",
spatial.biomass.nodes,
suffix=" solid biomass import",
bus0=["EU solid biomass import"],
bus1=spatial.biomass.nodes,
bus2="co2 atmosphere",
carrier="solid biomass import",
efficiency=1.0,
efficiency2=biomass_import_upstream_emissions
* costs.at["solid biomass", "CO2 intensity"],
p_nom_extendable=True,
)
n.madd(
"Link",
spatial.gas.biogas_to_gas,
@ -2359,6 +2458,19 @@ def add_biomass(n, costs):
carrier="solid biomass transport",
)
if options["municipal_solid_waste"]:
n.madd(
"Link",
biomass_transport.index,
bus0=biomass_transport.bus0 + " municipal solid waste",
bus1=biomass_transport.bus1 + " municipal solid waste",
p_nom_extendable=False,
p_nom=5e4,
length=biomass_transport.length.values,
marginal_cost=biomass_transport.costs * biomass_transport.length.values,
carrier="municipal solid waste transport",
)
elif options["biomass_spatial"]:
# add artificial biomass generators at nodes which include transport costs
transport_costs = pd.read_csv(
@ -2388,6 +2500,26 @@ def add_biomass(n, costs):
type="operational_limit",
)
if options["municipal_solid_waste"]:
# Add municipal solid waste
n.madd(
"Generator",
spatial.msw.nodes,
bus=spatial.msw.nodes,
carrier="municipal solid waste",
p_nom=10000,
marginal_cost=0 # costs.at["municipal solid waste", "fuel"]
+ bus_transport_costs * average_distance,
)
n.add(
"GlobalConstraint",
"msw limit",
carrier_attribute="municipal solid waste",
sense="<=",
constant=biomass_potentials["municipal solid waste"].sum(),
type="operational_limit",
)
# AC buses with district heating
urban_central = n.buses.index[n.buses.carrier == "urban central heat"]
if not urban_central.empty and options["chp"]:
@ -2420,28 +2552,23 @@ def add_biomass(n, costs):
bus4=spatial.co2.df.loc[urban_central, "nodes"].values,
carrier="urban central solid biomass CHP CC",
p_nom_extendable=True,
capital_cost=costs.at[key, "fixed"] * costs.at[key, "efficiency"]
capital_cost=costs.at[key + " CC", "fixed"]
* costs.at[key + " CC", "efficiency"]
+ costs.at["biomass CHP capture", "fixed"]
* costs.at["solid biomass", "CO2 intensity"],
marginal_cost=costs.at[key, "VOM"],
efficiency=costs.at[key, "efficiency"]
marginal_cost=costs.at[key + " CC", "VOM"],
efficiency=costs.at[key + " CC", "efficiency"]
- costs.at["solid biomass", "CO2 intensity"]
* (
costs.at["biomass CHP capture", "electricity-input"]
+ costs.at["biomass CHP capture", "compression-electricity-input"]
),
efficiency2=costs.at[key, "efficiency-heat"]
+ costs.at["solid biomass", "CO2 intensity"]
* (
costs.at["biomass CHP capture", "heat-output"]
+ costs.at["biomass CHP capture", "compression-heat-output"]
- costs.at["biomass CHP capture", "heat-input"]
),
efficiency2=costs.at[key + " CC", "efficiency-heat"],
efficiency3=-costs.at["solid biomass", "CO2 intensity"]
* costs.at["biomass CHP capture", "capture_rate"],
efficiency4=costs.at["solid biomass", "CO2 intensity"]
* costs.at["biomass CHP capture", "capture_rate"],
lifetime=costs.at[key, "lifetime"],
lifetime=costs.at[key + " CC", "lifetime"],
)
if options["biomass_boiler"]:
@ -2483,11 +2610,12 @@ def add_biomass(n, costs):
efficiency2=-costs.at["solid biomass", "CO2 intensity"]
+ costs.at["BtL", "CO2 stored"],
p_nom_extendable=True,
capital_cost=costs.at["BtL", "fixed"],
marginal_cost=costs.at["BtL", "efficiency"] * costs.at["BtL", "VOM"],
capital_cost=costs.at["BtL", "fixed"] * costs.at["BtL", "efficiency"],
marginal_cost=costs.at["BtL", "VOM"] * costs.at["BtL", "efficiency"],
)
# TODO: Update with energy penalty
# Assuming that acid gas removal (incl. CO2) from syngas i performed with Rectisol
# process (Methanol) and that electricity demand for this is included in the base process
n.madd(
"Link",
spatial.biomass.nodes,
@ -2503,9 +2631,46 @@ def add_biomass(n, costs):
+ costs.at["BtL", "CO2 stored"] * (1 - costs.at["BtL", "capture rate"]),
efficiency3=costs.at["BtL", "CO2 stored"] * costs.at["BtL", "capture rate"],
p_nom_extendable=True,
capital_cost=costs.at["BtL", "fixed"]
capital_cost=costs.at["BtL", "fixed"] * costs.at["BtL", "efficiency"]
+ costs.at["biomass CHP capture", "fixed"] * costs.at["BtL", "CO2 stored"],
marginal_cost=costs.at["BtL", "efficiency"] * costs.at["BtL", "VOM"],
marginal_cost=costs.at["BtL", "VOM"] * costs.at["BtL", "efficiency"],
)
# Electrobiofuels (BtL with hydrogen addition to make more use of biogenic carbon).
# Combination of efuels and biomass to liquid, both based on Fischer-Tropsch.
# Experimental version - use with caution
if options["electrobiofuels"]:
efuel_scale_factor = costs.at["BtL", "C stored"]
name = (
pd.Index(spatial.biomass.nodes)
+ " "
+ pd.Index(spatial.h2.nodes.str.replace(" H2", ""))
)
n.madd(
"Link",
name,
suffix=" electrobiofuels",
bus0=spatial.biomass.nodes,
bus1=spatial.oil.nodes,
bus2=spatial.h2.nodes,
bus3="co2 atmosphere",
carrier="electrobiofuels",
lifetime=costs.at["electrobiofuels", "lifetime"],
efficiency=costs.at["electrobiofuels", "efficiency-biomass"],
efficiency2=-costs.at["electrobiofuels", "efficiency-hydrogen"],
efficiency3=-costs.at["solid biomass", "CO2 intensity"]
+ costs.at["BtL", "CO2 stored"]
* (1 - costs.at["Fischer-Tropsch", "capture rate"]),
p_nom_extendable=True,
capital_cost=costs.at["BtL", "fixed"] * costs.at["BtL", "efficiency"]
+ efuel_scale_factor
* costs.at["Fischer-Tropsch", "fixed"]
* costs.at["Fischer-Tropsch", "efficiency"],
marginal_cost=costs.at["BtL", "VOM"] * costs.at["BtL", "efficiency"]
+ efuel_scale_factor
* costs.at["Fischer-Tropsch", "VOM"]
* costs.at["Fischer-Tropsch", "efficiency"],
)
# BioSNG from solid biomass
@ -2523,11 +2688,12 @@ def add_biomass(n, costs):
efficiency3=-costs.at["solid biomass", "CO2 intensity"]
+ costs.at["BioSNG", "CO2 stored"],
p_nom_extendable=True,
capital_cost=costs.at["BioSNG", "fixed"],
marginal_cost=costs.at["BioSNG", "efficiency"] * costs.at["BioSNG", "VOM"],
capital_cost=costs.at["BioSNG", "fixed"] * costs.at["BioSNG", "efficiency"],
marginal_cost=costs.at["BioSNG", "VOM"] * costs.at["BioSNG", "efficiency"],
)
# TODO: Update with energy penalty for CC
# Assuming that acid gas removal (incl. CO2) from syngas i performed with Rectisol
# process (Methanol) and that electricity demand for this is included in the base process
n.madd(
"Link",
spatial.biomass.nodes,
@ -2545,10 +2711,10 @@ def add_biomass(n, costs):
+ costs.at["BioSNG", "CO2 stored"]
* (1 - costs.at["BioSNG", "capture rate"]),
p_nom_extendable=True,
capital_cost=costs.at["BioSNG", "fixed"]
capital_cost=costs.at["BioSNG", "fixed"] * costs.at["BioSNG", "efficiency"]
+ costs.at["biomass CHP capture", "fixed"]
* costs.at["BioSNG", "CO2 stored"],
marginal_cost=costs.at["BioSNG", "efficiency"] * costs.at["BioSNG", "VOM"],
marginal_cost=costs.at["BioSNG", "VOM"] * costs.at["BioSNG", "efficiency"],
)
@ -2898,7 +3064,7 @@ def add_industry(n, costs):
carrier="oil",
)
if "oil" not in n.generators.carrier.unique():
if options.get("fossil_fuels", True) and "oil" not in n.generators.carrier.unique():
n.madd(
"Generator",
spatial.oil.nodes,
@ -3059,6 +3225,17 @@ def add_industry(n, costs):
efficiency3=process_co2_per_naphtha,
)
if options.get("biomass", True) and options["municipal_solid_waste"]:
n.madd(
"Link",
spatial.msw.locations,
bus0=spatial.msw.nodes,
bus1=non_sequestered_hvc_locations,
carrier="municipal solid waste",
p_nom_extendable=True,
efficiency=1.0,
)
n.madd(
"Link",
spatial.oil.demand_locations,
@ -3108,7 +3285,9 @@ def add_industry(n, costs):
carrier="waste CHP CC",
p_nom_extendable=True,
capital_cost=costs.at["waste CHP CC", "fixed"]
* costs.at["waste CHP CC", "efficiency"],
* costs.at["waste CHP CC", "efficiency"]
+ costs.at["biomass CHP capture", "fixed"]
* costs.at["oil", "CO2 intensity"],
marginal_cost=costs.at["waste CHP CC", "VOM"],
efficiency=costs.at["waste CHP CC", "efficiency"],
efficiency2=costs.at["waste CHP CC", "efficiency-heat"],
@ -3949,7 +4128,7 @@ if __name__ == "__main__":
"prepare_sector_network",
simpl="",
opts="",
clusters="1",
clusters="37",
ll="vopt",
sector_opts="",
planning_horizons="2050",