From 35050d9f840a4d1a51247cc12d9c804553a88e8f Mon Sep 17 00:00:00 2001 From: Philipp Glaum <95913147+p-glaum@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:20:15 +0100 Subject: [PATCH] make chp fuel flexible (#1392) * make chp flexible * default config: add settings prepare_sector_network: adress Fabians comments docs: add new config settings to doc * add release note * fix getattr bug * prepare_sector_network: use "fuel" intensity intensity for CC unit instead of "gas" co2 intensity --- config/config.default.yaml | 4 +- doc/configtables/sector.csv | 4 +- doc/release_notes.rst | 2 + scripts/prepare_sector_network.py | 114 ++++++++++++++++-------------- 4 files changed, 68 insertions(+), 56 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index a475c6fdf..9a4f0de8a 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -597,7 +597,9 @@ sector: overdimension_heat_generators: decentral: 1.1 #to cover demand peaks bigger than data central: 1.0 - chp: true + chp: + enable: true + fuel: gas # for all fuels the same techno economic data from gas CHP is taken micro_chp: false solar_thermal: true solar_cf_correction: 0.788457 # = >>> 1/1.2683 diff --git a/doc/configtables/sector.csv b/doc/configtables/sector.csv index eeee192eb..26d5a9440 100644 --- a/doc/configtables/sector.csv +++ b/doc/configtables/sector.csv @@ -93,7 +93,9 @@ biomass_boiler,--,"{true, false}",Add option for transforming biomass into heat overdimension_heat_generators,,,Add option for overdimensioning 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. -- decentral,--,float,The factor for overdimensioning (increasing CAPEX) decentral heating systems -- central,--,float,The factor for overdimensioning (increasing CAPEX) central heating systems -chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP) +chp,--,, +-- enable,--,"{true, false}",Add option for using Combined Heat and Power (CHP) +-- fuel,--,string or list of fuels,"Possible options are all fuels which have an exisitng bus and their CO2 intensity is given in the technology data. Currently possible are ""gas"", ""oil"", ""methanol"", ""lignite"", ""coal"". For all fuels, the techno-economic data from gas CHP is used." 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. solar_cf_correction,--,float,The correction factor for the value provided by the solar thermal profile calculations diff --git a/doc/release_notes.rst b/doc/release_notes.rst index bb37ef1d9..2a2b56a6b 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -11,6 +11,8 @@ Release Notes Upcoming Release ================ +* Feature: Allow CHPs to use different fuel sources such as gas, oil, coal, and methanol. Note that the cost assumptions are based on a gas CHP. + * Improve `sanitize_carrier`` function by filling in colors of missing carriers with colors mapped after using the function `rename_techs`. * Bugfix: Adjusted efficiency2 (to atmosphere) for bioliquids-to-oil Link in `prepare_sector_network` to exactly offset the corresponding oil emissions. diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 2c77e0e97..a815024fd 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -2282,62 +2282,68 @@ def add_heat(n: pypsa.Network, costs: pd.DataFrame, cop: xr.DataArray): ], ) - if options["chp"] and heat_system == HeatSystem.URBAN_CENTRAL: + if options["chp"]["enable"] and heat_system == HeatSystem.URBAN_CENTRAL: # add gas CHP; biomass CHP is added in biomass section - n.add( - "Link", - nodes + " urban central gas CHP", - bus0=spatial.gas.df.loc[nodes, "nodes"].values, - bus1=nodes, - bus2=nodes + " urban central heat", - bus3="co2 atmosphere", - carrier="urban central gas CHP", - p_nom_extendable=True, - capital_cost=costs.at["central gas CHP", "fixed"] - * costs.at["central gas CHP", "efficiency"], - marginal_cost=costs.at["central gas CHP", "VOM"], - efficiency=costs.at["central gas CHP", "efficiency"], - efficiency2=costs.at["central gas CHP", "efficiency"] - / costs.at["central gas CHP", "c_b"], - efficiency3=costs.at["gas", "CO2 intensity"], - lifetime=costs.at["central gas CHP", "lifetime"], - ) + fuels = options["chp"]["fuel"] + fuels = np.atleast_1d(fuels) + for fuel in fuels: + fuel_nodes = getattr(spatial, fuel).df + n.add( + "Link", + nodes + f" urban central {fuel} CHP", + bus0=fuel_nodes.loc[nodes, "nodes"].values, + bus1=nodes, + bus2=nodes + " urban central heat", + bus3="co2 atmosphere", + carrier="urban central CHP", + p_nom_extendable=True, + capital_cost=costs.at["central gas CHP", "fixed"] + * costs.at["central gas CHP", "efficiency"], + marginal_cost=costs.at["central gas CHP", "VOM"], + efficiency=costs.at["central gas CHP", "efficiency"], + efficiency2=costs.at["central gas CHP", "efficiency"] + / costs.at["central gas CHP", "c_b"], + efficiency3=costs.at[fuel, "CO2 intensity"], + lifetime=costs.at["central gas CHP", "lifetime"], + ) - n.add( - "Link", - nodes + " urban central gas CHP CC", - bus0=spatial.gas.df.loc[nodes, "nodes"].values, - bus1=nodes, - bus2=nodes + " urban central heat", - bus3="co2 atmosphere", - bus4=spatial.co2.df.loc[nodes, "nodes"].values, - carrier="urban central gas CHP CC", - p_nom_extendable=True, - capital_cost=costs.at["central gas CHP", "fixed"] - * costs.at["central gas CHP", "efficiency"] - + costs.at["biomass CHP capture", "fixed"] - * costs.at["gas", "CO2 intensity"], - marginal_cost=costs.at["central gas CHP", "VOM"], - efficiency=costs.at["central gas CHP", "efficiency"] - - costs.at["gas", "CO2 intensity"] - * ( - costs.at["biomass CHP capture", "electricity-input"] - + costs.at["biomass CHP capture", "compression-electricity-input"] - ), - efficiency2=costs.at["central gas CHP", "efficiency"] - / costs.at["central gas CHP", "c_b"] - + costs.at["gas", "CO2 intensity"] - * ( - costs.at["biomass CHP capture", "heat-output"] - + costs.at["biomass CHP capture", "compression-heat-output"] - - costs.at["biomass CHP capture", "heat-input"] - ), - efficiency3=costs.at["gas", "CO2 intensity"] - * (1 - costs.at["biomass CHP capture", "capture_rate"]), - efficiency4=costs.at["gas", "CO2 intensity"] - * costs.at["biomass CHP capture", "capture_rate"], - lifetime=costs.at["central gas CHP", "lifetime"], - ) + n.add( + "Link", + nodes + f" urban central {fuel} CHP CC", + bus0=fuel_nodes.loc[nodes, "nodes"].values, + bus1=nodes, + bus2=nodes + " urban central heat", + bus3="co2 atmosphere", + bus4=spatial.co2.df.loc[nodes, "nodes"].values, + carrier="urban central CHP CC", + p_nom_extendable=True, + capital_cost=costs.at["central gas CHP", "fixed"] + * costs.at["central gas CHP", "efficiency"] + + costs.at["biomass CHP capture", "fixed"] + * costs.at[fuel, "CO2 intensity"], + marginal_cost=costs.at["central gas CHP", "VOM"], + efficiency=costs.at["central gas CHP", "efficiency"] + - costs.at[fuel, "CO2 intensity"] + * ( + costs.at["biomass CHP capture", "electricity-input"] + + costs.at[ + "biomass CHP capture", "compression-electricity-input" + ] + ), + efficiency2=costs.at["central gas CHP", "efficiency"] + / costs.at["central gas CHP", "c_b"] + + costs.at[fuel, "CO2 intensity"] + * ( + costs.at["biomass CHP capture", "heat-output"] + + costs.at["biomass CHP capture", "compression-heat-output"] + - costs.at["biomass CHP capture", "heat-input"] + ), + efficiency3=costs.at[fuel, "CO2 intensity"] + * (1 - costs.at["biomass CHP capture", "capture_rate"]), + efficiency4=costs.at[fuel, "CO2 intensity"] + * costs.at["biomass CHP capture", "capture_rate"], + lifetime=costs.at["central gas CHP", "lifetime"], + ) if ( options["chp"]