Merge pull request #737 from PyPSA/wildcard-opts-config
Add wildcards option in config (full backward compatibility)
This commit is contained in:
commit
f6fbd00787
@ -59,6 +59,9 @@ snapshots:
|
|||||||
start: "2013-01-01"
|
start: "2013-01-01"
|
||||||
end: "2014-01-01"
|
end: "2014-01-01"
|
||||||
inclusive: 'left'
|
inclusive: 'left'
|
||||||
|
resolution: false
|
||||||
|
segmentation: false
|
||||||
|
#representative: false
|
||||||
|
|
||||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#enable
|
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#enable
|
||||||
enable:
|
enable:
|
||||||
@ -74,6 +77,7 @@ enable:
|
|||||||
retrieve_natura_raster: true
|
retrieve_natura_raster: true
|
||||||
custom_busmap: false
|
custom_busmap: false
|
||||||
|
|
||||||
|
|
||||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#co2-budget
|
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#co2-budget
|
||||||
co2_budget:
|
co2_budget:
|
||||||
2020: 0.701
|
2020: 0.701
|
||||||
@ -87,7 +91,9 @@ co2_budget:
|
|||||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#electricity
|
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#electricity
|
||||||
electricity:
|
electricity:
|
||||||
voltages: [220., 300., 380., 500., 750.]
|
voltages: [220., 300., 380., 500., 750.]
|
||||||
|
gaslimit_enable: false
|
||||||
gaslimit: false
|
gaslimit: false
|
||||||
|
co2limit_enable: false
|
||||||
co2limit: 7.75e+7
|
co2limit: 7.75e+7
|
||||||
co2base: 1.487e+9
|
co2base: 1.487e+9
|
||||||
agg_p_nom_limits: data/agg_p_nom_minmax.csv
|
agg_p_nom_limits: data/agg_p_nom_minmax.csv
|
||||||
@ -124,6 +130,10 @@ electricity:
|
|||||||
Onshore: [onwind]
|
Onshore: [onwind]
|
||||||
PV: [solar]
|
PV: [solar]
|
||||||
|
|
||||||
|
autarky:
|
||||||
|
enable: false
|
||||||
|
by_country: false
|
||||||
|
|
||||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#atlite
|
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#atlite
|
||||||
atlite:
|
atlite:
|
||||||
default_cutout: europe-2013-era5
|
default_cutout: europe-2013-era5
|
||||||
@ -618,7 +628,9 @@ costs:
|
|||||||
battery: 0.
|
battery: 0.
|
||||||
battery inverter: 0.
|
battery inverter: 0.
|
||||||
emission_prices:
|
emission_prices:
|
||||||
|
enable: false
|
||||||
co2: 0.
|
co2: 0.
|
||||||
|
co2_monthly_prices: false
|
||||||
|
|
||||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#clustering
|
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#clustering
|
||||||
clustering:
|
clustering:
|
||||||
@ -660,6 +672,12 @@ solving:
|
|||||||
linearized_unit_commitment: true
|
linearized_unit_commitment: true
|
||||||
horizon: 365
|
horizon: 365
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
CCL: false
|
||||||
|
EQ: false
|
||||||
|
BAU: false
|
||||||
|
SAFE: false
|
||||||
|
|
||||||
solver:
|
solver:
|
||||||
name: gurobi
|
name: gurobi
|
||||||
options: gurobi-default
|
options: gurobi-default
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
,Unit,Values,Description
|
,Unit,Values,Description
|
||||||
year,--,"YYYY; e.g. '2030'","Year for which to retrieve cost assumptions of ``resources/costs.csv``."
|
year,--,YYYY; e.g. '2030',Year for which to retrieve cost assumptions of ``resources/costs.csv``.
|
||||||
version,--,"vX.X.X; e.g. 'v0.5.0'","Version of ``technology-data`` repository to use."
|
version,--,vX.X.X; e.g. 'v0.5.0',Version of ``technology-data`` repository to use.
|
||||||
rooftop_share,--,float,"Share of rooftop PV when calculating capital cost of solar (joint rooftop and utility-scale PV)."
|
rooftop_share,--,float,Share of rooftop PV when calculating capital cost of solar (joint rooftop and utility-scale PV).
|
||||||
fill_values,--,float,"Default values if not specified for a technology in ``resources/costs.csv``."
|
fill_values,--,float,Default values if not specified for a technology in ``resources/costs.csv``.
|
||||||
capital_cost,EUR/MW,"Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.","For the given technologies, assumptions about their capital investment costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
|
capital_cost,EUR/MW,Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.,"For the given technologies, assumptions about their capital investment costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
|
||||||
marginal_cost,EUR/MWh,"Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.","For the given technologies, assumptions about their marginal operating costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
|
marginal_cost,EUR/MWh,Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.,"For the given technologies, assumptions about their marginal operating costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
|
||||||
emission_prices,,,"Specify exogenous prices for emission types listed in ``network.carriers`` to marginal costs."
|
emission_prices,,,Specify exogenous prices for emission types listed in ``network.carriers`` to marginal costs.
|
||||||
-- co2,EUR/t,float,"Exogenous price of carbon-dioxide added to the marginal costs of fossil-fuelled generators according to their carbon intensity. Added through the keyword ``Ep`` in the ``{opts}`` wildcard only in the rule :mod:`prepare_network``."
|
-- enable,bool,true or false,Add cost for a carbon-dioxide price configured in ``costs: emission_prices: co2`` to ``marginal_cost`` of generators (other emission types listed in ``network.carriers`` possible as well)
|
||||||
|
-- co2,EUR/t,float,Exogenous price of carbon-dioxide added to the marginal costs of fossil-fuelled generators according to their carbon intensity. Added through the keyword ``Ep`` in the ``{opts}`` wildcard only in the rule :mod:`prepare_network``.
|
||||||
|
-- co2_monthly_price,bool,true or false,Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``
|
||||||
|
|
@ -1,6 +1,8 @@
|
|||||||
,Unit,Values,Description
|
,Unit,Values,Description
|
||||||
voltages,kV,"Any subset of {220., 300., 380.}",Voltage levels to consider
|
voltages,kV,"Any subset of {220., 300., 380.}",Voltage levels to consider
|
||||||
|
gaslimit_enable,bool,true or false,Add an overall absolute gas limit configured in ``electricity: gaslimit``.
|
||||||
gaslimit,MWhth,float or false,Global gas usage limit
|
gaslimit,MWhth,float or false,Global gas usage limit
|
||||||
|
co2limit_enable,bool,true or false,Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit``.
|
||||||
co2limit,:math:`t_{CO_2-eq}/a`,float,Cap on total annual system carbon dioxide emissions
|
co2limit,:math:`t_{CO_2-eq}/a`,float,Cap on total annual system carbon dioxide emissions
|
||||||
co2base,:math:`t_{CO_2-eq}/a`,float,Reference value of total annual system carbon dioxide emissions if relative emission reduction target is specified in ``{opts}`` wildcard.
|
co2base,:math:`t_{CO_2-eq}/a`,float,Reference value of total annual system carbon dioxide emissions if relative emission reduction target is specified in ``{opts}`` wildcard.
|
||||||
agg_p_nom_limits,file,path,Reference to ``.csv`` file specifying per carrier generator nominal capacity constraints for individual countries if ``'CCL'`` is in ``{opts}`` wildcard. Defaults to ``data/agg_p_nom_minmax.csv``.
|
agg_p_nom_limits,file,path,Reference to ``.csv`` file specifying per carrier generator nominal capacity constraints for individual countries if ``'CCL'`` is in ``{opts}`` wildcard. Defaults to ``data/agg_p_nom_minmax.csv``.
|
||||||
@ -34,3 +36,6 @@ estimate_renewable_capacities,,,
|
|||||||
-- -- Offshore,--,"Any subset of {offwind-ac, offwind-dc}","List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) onshore technology."
|
-- -- Offshore,--,"Any subset of {offwind-ac, offwind-dc}","List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) onshore technology."
|
||||||
-- -- Offshore,--,{onwind},"List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) offshore technology."
|
-- -- Offshore,--,{onwind},"List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) offshore technology."
|
||||||
-- -- PV,--,{solar},"List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) PV technology."
|
-- -- PV,--,{solar},"List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) PV technology."
|
||||||
|
autarky,,,
|
||||||
|
-- enable,bool,true or false,Require each node to be autarkic by removing all lines and links.
|
||||||
|
-- by_country,bool,true or false,Require each country to be autarkic by removing all cross-border lines and links. ``electricity: autarky`` must be enabled.
|
||||||
|
|
@ -1,13 +1,13 @@
|
|||||||
Trigger, Description, Definition, Status
|
Trigger, Description, Definition, Status
|
||||||
``nH``; i.e. ``2H``-``6H``, Resample the time-resolution by averaging over every ``n`` snapshots, ``prepare_network``: `average_every_nhours() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L110>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L146>`__), In active use
|
``nH``; i.e. ``2H``-``6H``, Resample the time-resolution by averaging over every ``n`` snapshots, ``prepare_network``: `average_every_nhours() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L110>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L146>`__), In active use
|
||||||
``nSEG``; e.g. ``4380SEG``, "Apply time series segmentation with `tsam <https://tsam.readthedocs.io/en/latest/index.html>`_ package to ``n`` adjacent snapshots of varying lengths based on capacity factors of varying renewables, hydro inflow and load.", ``prepare_network``: apply_time_segmentation(), In active use
|
``nSEG``; e.g. ``4380SEG``,"Apply time series segmentation with `tsam <https://tsam.readthedocs.io/en/latest/index.html>`_ package to ``n`` adjacent snapshots of varying lengths based on capacity factors of varying renewables, hydro inflow and load.", ``prepare_network``: apply_time_segmentation(), In active use
|
||||||
``Co2L``, Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit``. If a float is appended an overall emission limit relative to the emission level given in ``electricity: co2base`` is added (e.g. ``Co2L0.05`` limits emissisions to 5% of what is given in ``electricity: co2base``), ``prepare_network``: `add_co2limit() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L19>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L154>`__, In active use
|
``Co2L``,Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit``. If a float is appended an overall emission limit relative to the emission level given in ``electricity: co2base`` is added (e.g. ``Co2L0.05`` limits emissisions to 5% of what is given in ``electricity: co2base``), ``prepare_network``: `add_co2limit() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L19>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L154>`__, In active use
|
||||||
``Ep``, Add cost for a carbon-dioxide price configured in ``costs: emission_prices: co2`` to ``marginal_cost`` of generators (other emission types listed in ``network.carriers`` possible as well), ``prepare_network``: `add_emission_prices() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L24>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L158>`__, In active use
|
``Ep``,Add cost for a carbon-dioxide price configured in ``costs: emission_prices: co2`` to ``marginal_cost`` of generators (other emission types listed in ``network.carriers`` possible as well), ``prepare_network``: `add_emission_prices() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L24>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L158>`__, In active use
|
||||||
``Ept``, Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``, In active use
|
``Ept``,Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``, In active use,
|
||||||
``CCL``, Add minimum and maximum levels of generator nominal capacity per carrier for individual countries. These can be specified in the file linked at ``electricity: agg_p_nom_limits`` in the configuration. File defaults to ``data/agg_p_nom_minmax.csv``., ``solve_network``, In active use
|
``CCL``,Add minimum and maximum levels of generator nominal capacity per carrier for individual countries. These can be specified in the file linked at ``electricity: agg_p_nom_limits`` in the configuration. File defaults to ``data/agg_p_nom_minmax.csv``., ``solve_network``, In active use
|
||||||
``EQ``, "Require each country or node to on average produce a minimal share of its total consumption itself. Example: ``EQ0.5c`` demands each country to produce on average at least 50% of its consumption; ``EQ0.5`` demands each node to produce on average at least 50% of its consumption.", ``solve_network``, In active use
|
``EQ``,Require each country or node to on average produce a minimal share of its total consumption itself. Example: ``EQ0.5c`` demands each country to produce on average at least 50% of its consumption; ``EQ0.5`` demands each node to produce on average at least 50% of its consumption., ``solve_network``, In active use
|
||||||
``ATK``, "Require each node to be autarkic. Example: ``ATK`` removes all lines and links. ``ATKc`` removes all cross-border lines and links.", ``prepare_network``, In active use
|
``ATK``,Require each node to be autarkic. Example: ``ATK`` removes all lines and links. ``ATKc`` removes all cross-border lines and links., ``prepare_network``, In active use
|
||||||
``BAU``, Add a per-``carrier`` minimal overall capacity; i.e. at least ``40GW`` of ``OCGT`` in Europe; configured in ``electricity: BAU_mincapacities``, ``solve_network``: `add_opts_constraints() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/solve_network.py#L66>`__, Untested
|
``BAU``,Add a per-``carrier`` minimal overall capacity; i.e. at least ``40GW`` of ``OCGT`` in Europe; configured in ``electricity: BAU_mincapacities``, ``solve_network``: `add_opts_constraints() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/solve_network.py#L66>`__, Untested
|
||||||
``SAFE``, Add a capacity reserve margin of a certain fraction above the peak demand to which renewable generators and storage do *not* contribute. Ignores network., ``solve_network`` `add_opts_constraints() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/solve_network.py#L73>`__, Untested
|
``SAFE``,Add a capacity reserve margin of a certain fraction above the peak demand to which renewable generators and storage do *not* contribute. Ignores network., ``solve_network`` `add_opts_constraints() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/solve_network.py#L73>`__, Untested
|
||||||
``carrier+{c|p|m}factor``,"Alter the capital cost (``c``), installable potential (``p``) or marginal costs (``m``) of a carrier by a factor. Example: ``solar+c0.5`` reduces the capital cost of solar to 50\% of original values.", ``prepare_network``, In active use
|
``carrier+{c|p|m}factor``,"Alter the capital cost (``c``), installable potential (``p``) or marginal costs (``m``) of a carrier by a factor. Example: ``solar+c0.5`` reduces the capital cost of solar to 50\% of original values.", ``prepare_network``, In active use
|
||||||
``CH4L``,"Add an overall absolute gas limit. If configured in ``electricity: gaslimit`` it is given in MWh thermal, if a float is appended, the overall gaslimit is assumed to be given in TWh thermal (e.g. ``CH4L200`` limits gas dispatch to 200 TWh termal)", ``prepare_network``: ``add_gaslimit()``, In active use
|
``CH4L``,"Add an overall absolute gas limit. If configured in ``electricity: gaslimit`` it is given in MWh thermal, if a float is appended, the overall gaslimit is assumed to be given in TWh thermal (e.g. ``CH4L200`` limits gas dispatch to 200 TWh termal)", ``prepare_network``: ``add_gaslimit()``, In active use
|
||||||
|
Can't render this file because it has a wrong number of fields in line 6.
|
@ -1,4 +1,6 @@
|
|||||||
,Unit,Values,Description
|
,Unit,Values,Description
|
||||||
start,--,"str or datetime-like; e.g. YYYY-MM-DD","Left bound of date range"
|
start,--,str or datetime-like; e.g. YYYY-MM-DD,Left bound of date range
|
||||||
end,--,"str or datetime-like; e.g. YYYY-MM-DD","Right bound of date range"
|
end,--,str or datetime-like; e.g. YYYY-MM-DD,Right bound of date range
|
||||||
inclusive,--,"One of {'neither', 'both', ‘left’, ‘right’}","Make the time interval closed to the ``left``, ``right``, or both sides ``both`` or neither side ``None``."
|
inclusive,--,"One of {'neither', 'both', ‘left’, ‘right’}","Make the time interval closed to the ``left``, ``right``, or both sides ``both`` or neither side ``None``."
|
||||||
|
resolution ,--,"{false,``nH``; i.e. ``2H``-``6H``}",Resample the time-resolution by averaging over every ``n`` snapshots
|
||||||
|
segmentation,--,"{false,``n``; e.g. ``4380``}","Apply time series segmentation with `tsam <https://tsam.readthedocs.io/en/latest/index.html>`_ package to ``n`` adjacent snapshots of varying lengths based on capacity factors of varying renewables, hydro inflow and load."
|
||||||
|
|
@ -13,6 +13,11 @@ options,,,
|
|||||||
-- transmission_losses,int,[0-9],"Add piecewise linear approximation of transmission losses based on n tangents. Defaults to 0, which means losses are ignored."
|
-- transmission_losses,int,[0-9],"Add piecewise linear approximation of transmission losses based on n tangents. Defaults to 0, which means losses are ignored."
|
||||||
-- linearized_unit_commitment,bool,"{'true','false'}",Whether to optimise using the linearized unit commitment formulation.
|
-- linearized_unit_commitment,bool,"{'true','false'}",Whether to optimise using the linearized unit commitment formulation.
|
||||||
-- horizon,--,int,Number of snapshots to consider in each iteration. Defaults to 100.
|
-- horizon,--,int,Number of snapshots to consider in each iteration. Defaults to 100.
|
||||||
|
constraints ,,,
|
||||||
|
-- CCL,bool,"{'true','false'}",Add minimum and maximum levels of generator nominal capacity per carrier for individual countries. These can be specified in the file linked at ``electricity: agg_p_nom_limits`` in the configuration. File defaults to ``data/agg_p_nom_minmax.csv``.
|
||||||
|
-- EQ,bool/string,"{'false',`n(c| )``; i.e. ``0.5``-``0.7c``}",Require each country or node to on average produce a minimal share of its total consumption itself. Example: ``EQ0.5c`` demands each country to produce on average at least 50% of its consumption; ``EQ0.5`` demands each node to produce on average at least 50% of its consumption.
|
||||||
|
-- BAU,bool,"{'true','false'}",Add a per-``carrier`` minimal overall capacity; i.e. at least ``40GW`` of ``OCGT`` in Europe; configured in ``electricity: BAU_mincapacities``
|
||||||
|
-- SAFE,bool,"{'true','false'}",Add a capacity reserve margin of a certain fraction above the peak demand to which renewable generators and storage do *not* contribute. Ignores network.
|
||||||
solver,,,
|
solver,,,
|
||||||
-- name,--,"One of {'gurobi', 'cplex', 'cbc', 'glpk', 'ipopt'}; potentially more possible",Solver to use for optimisation problems in the workflow; e.g. clustering and linear optimal power flow.
|
-- name,--,"One of {'gurobi', 'cplex', 'cbc', 'glpk', 'ipopt'}; potentially more possible",Solver to use for optimisation problems in the workflow; e.g. clustering and linear optimal power flow.
|
||||||
-- options,--,Key listed under ``solver_options``.,Link to specific parameter settings.
|
-- options,--,Key listed under ``solver_options``.,Link to specific parameter settings.
|
||||||
|
|
@ -10,6 +10,11 @@ Release Notes
|
|||||||
Upcoming Release
|
Upcoming Release
|
||||||
================
|
================
|
||||||
|
|
||||||
|
* More wildcard options now have a corresponding config entry. If the wildcard
|
||||||
|
is given, then its value is used. If the wildcard is not given but the options
|
||||||
|
in config are enabled, then the value from config is used. If neither is
|
||||||
|
given, the options are skipped.
|
||||||
|
|
||||||
* Distinguish between stored and sequestered CO2. Stored CO2 is stored
|
* Distinguish between stored and sequestered CO2. Stored CO2 is stored
|
||||||
overground in tanks and can be used for CCU (e.g. methanolisation).
|
overground in tanks and can be used for CCU (e.g. methanolisation).
|
||||||
Sequestered CO2 is stored underground and can no longer be used for CCU. This
|
Sequestered CO2 is stored underground and can no longer be used for CCU. This
|
||||||
|
@ -20,7 +20,7 @@ if config["enable"].get("prepare_links_p_nom", False):
|
|||||||
|
|
||||||
rule build_electricity_demand:
|
rule build_electricity_demand:
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
countries=config["countries"],
|
countries=config["countries"],
|
||||||
load=config["load"],
|
load=config["load"],
|
||||||
input:
|
input:
|
||||||
@ -61,7 +61,7 @@ rule build_powerplants:
|
|||||||
rule base_network:
|
rule base_network:
|
||||||
params:
|
params:
|
||||||
countries=config["countries"],
|
countries=config["countries"],
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
lines=config["lines"],
|
lines=config["lines"],
|
||||||
links=config["links"],
|
links=config["links"],
|
||||||
transformers=config["transformers"],
|
transformers=config["transformers"],
|
||||||
@ -144,7 +144,7 @@ if config["enable"].get("build_cutout", False):
|
|||||||
|
|
||||||
rule build_cutout:
|
rule build_cutout:
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
cutouts=config["atlite"]["cutouts"],
|
cutouts=config["atlite"]["cutouts"],
|
||||||
input:
|
input:
|
||||||
regions_onshore=RESOURCES + "regions_onshore.geojson",
|
regions_onshore=RESOURCES + "regions_onshore.geojson",
|
||||||
@ -258,6 +258,7 @@ else:
|
|||||||
|
|
||||||
rule build_renewable_profiles:
|
rule build_renewable_profiles:
|
||||||
params:
|
params:
|
||||||
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
renewable=config["renewable"],
|
renewable=config["renewable"],
|
||||||
input:
|
input:
|
||||||
**opt,
|
**opt,
|
||||||
@ -354,6 +355,8 @@ rule build_hydro_profile:
|
|||||||
if config["lines"]["dynamic_line_rating"]["activate"]:
|
if config["lines"]["dynamic_line_rating"]["activate"]:
|
||||||
|
|
||||||
rule build_line_rating:
|
rule build_line_rating:
|
||||||
|
params:
|
||||||
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
input:
|
input:
|
||||||
base_network=RESOURCES + "networks/base.nc",
|
base_network=RESOURCES + "networks/base.nc",
|
||||||
cutout="cutouts/"
|
cutout="cutouts/"
|
||||||
@ -531,13 +534,20 @@ rule add_extra_components:
|
|||||||
|
|
||||||
rule prepare_network:
|
rule prepare_network:
|
||||||
params:
|
params:
|
||||||
|
snapshots={
|
||||||
|
"resolution": config["snapshots"].get("resolution", False),
|
||||||
|
"segmentation": config["snapshots"].get("segmentation", False),
|
||||||
|
},
|
||||||
links=config["links"],
|
links=config["links"],
|
||||||
lines=config["lines"],
|
lines=config["lines"],
|
||||||
co2base=config["electricity"]["co2base"],
|
co2base=config["electricity"]["co2base"],
|
||||||
|
co2limit_enable=config["electricity"].get("co2limit_enable", False),
|
||||||
co2limit=config["electricity"]["co2limit"],
|
co2limit=config["electricity"]["co2limit"],
|
||||||
|
gaslimit_enable=config["electricity"].get("gaslimit_enable", False),
|
||||||
gaslimit=config["electricity"].get("gaslimit"),
|
gaslimit=config["electricity"].get("gaslimit"),
|
||||||
max_hours=config["electricity"]["max_hours"],
|
max_hours=config["electricity"]["max_hours"],
|
||||||
costs=config["costs"],
|
costs=config["costs"],
|
||||||
|
autarky=config["electricity"].get("autarky", {}),
|
||||||
input:
|
input:
|
||||||
RESOURCES + "networks/elec_s{simpl}_{clusters}_ec.nc",
|
RESOURCES + "networks/elec_s{simpl}_{clusters}_ec.nc",
|
||||||
tech_costs=COSTS,
|
tech_costs=COSTS,
|
||||||
|
@ -125,7 +125,7 @@ rule cluster_gas_network:
|
|||||||
|
|
||||||
rule build_heat_demands:
|
rule build_heat_demands:
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
input:
|
input:
|
||||||
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
|
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
|
||||||
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
|
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
|
||||||
@ -147,7 +147,7 @@ rule build_heat_demands:
|
|||||||
|
|
||||||
rule build_temperature_profiles:
|
rule build_temperature_profiles:
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
input:
|
input:
|
||||||
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
|
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
|
||||||
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
|
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
|
||||||
@ -199,7 +199,7 @@ rule build_cop_profiles:
|
|||||||
|
|
||||||
rule build_solar_thermal_profiles:
|
rule build_solar_thermal_profiles:
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
solar_thermal=config["solar_thermal"],
|
solar_thermal=config["solar_thermal"],
|
||||||
input:
|
input:
|
||||||
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
|
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
|
||||||
@ -662,7 +662,7 @@ rule build_shipping_demand:
|
|||||||
|
|
||||||
rule build_transport_demand:
|
rule build_transport_demand:
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
sector=config["sector"],
|
sector=config["sector"],
|
||||||
input:
|
input:
|
||||||
clustered_pop_layout=RESOURCES + "pop_layout_elec_s{simpl}_{clusters}.csv",
|
clustered_pop_layout=RESOURCES + "pop_layout_elec_s{simpl}_{clusters}.csv",
|
||||||
|
@ -85,7 +85,7 @@ rule make_summary:
|
|||||||
params:
|
params:
|
||||||
foresight=config["foresight"],
|
foresight=config["foresight"],
|
||||||
costs=config["costs"],
|
costs=config["costs"],
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
scenario=config["scenario"],
|
scenario=config["scenario"],
|
||||||
RDIR=RDIR,
|
RDIR=RDIR,
|
||||||
input:
|
input:
|
||||||
|
@ -17,7 +17,7 @@ rule build_electricity_production:
|
|||||||
The data is used for validation of the optimization results.
|
The data is used for validation of the optimization results.
|
||||||
"""
|
"""
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
countries=config["countries"],
|
countries=config["countries"],
|
||||||
output:
|
output:
|
||||||
RESOURCES + "historical_electricity_production.csv",
|
RESOURCES + "historical_electricity_production.csv",
|
||||||
@ -35,7 +35,7 @@ rule build_cross_border_flows:
|
|||||||
The data is used for validation of the optimization results.
|
The data is used for validation of the optimization results.
|
||||||
"""
|
"""
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
countries=config["countries"],
|
countries=config["countries"],
|
||||||
input:
|
input:
|
||||||
network=RESOURCES + "networks/base.nc",
|
network=RESOURCES + "networks/base.nc",
|
||||||
@ -55,7 +55,7 @@ rule build_electricity_prices:
|
|||||||
The data is used for validation of the optimization results.
|
The data is used for validation of the optimization results.
|
||||||
"""
|
"""
|
||||||
params:
|
params:
|
||||||
snapshots=config["snapshots"],
|
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
|
||||||
countries=config["countries"],
|
countries=config["countries"],
|
||||||
output:
|
output:
|
||||||
RESOURCES + "historical_electricity_prices.csv",
|
RESOURCES + "historical_electricity_prices.csv",
|
||||||
|
@ -7,6 +7,7 @@ import contextlib
|
|||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@ -23,6 +24,35 @@ logger = logging.getLogger(__name__)
|
|||||||
REGION_COLS = ["geometry", "name", "x", "y", "country"]
|
REGION_COLS = ["geometry", "name", "x", "y", "country"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_opt(opts, expr, flags=None):
|
||||||
|
"""
|
||||||
|
Return the first option matching the regular expression.
|
||||||
|
|
||||||
|
The regular expression is case-insensitive by default.
|
||||||
|
"""
|
||||||
|
if flags is None:
|
||||||
|
flags = re.IGNORECASE
|
||||||
|
for o in opts:
|
||||||
|
match = re.match(expr, o, flags=flags)
|
||||||
|
if match:
|
||||||
|
return match.group(0)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def find_opt(opts, expr):
|
||||||
|
"""
|
||||||
|
Return if available the float after the expression.
|
||||||
|
"""
|
||||||
|
for o in opts:
|
||||||
|
if expr in o:
|
||||||
|
m = re.findall("[0-9]*\.?[0-9]+$", o)
|
||||||
|
if len(m) > 0:
|
||||||
|
return True, float(m[0])
|
||||||
|
else:
|
||||||
|
return True, None
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
|
||||||
# Define a context manager to temporarily mute print statements
|
# Define a context manager to temporarily mute print statements
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def mute_print():
|
def mute_print():
|
||||||
|
@ -725,11 +725,12 @@ def base_network(
|
|||||||
transformers = _set_electrical_parameters_transformers(transformers, config)
|
transformers = _set_electrical_parameters_transformers(transformers, config)
|
||||||
links = _set_electrical_parameters_links(links, config, links_p_nom)
|
links = _set_electrical_parameters_links(links, config, links_p_nom)
|
||||||
converters = _set_electrical_parameters_converters(converters, config)
|
converters = _set_electrical_parameters_converters(converters, config)
|
||||||
|
snapshots = snakemake.params.snapshots
|
||||||
|
|
||||||
n = pypsa.Network()
|
n = pypsa.Network()
|
||||||
n.name = "PyPSA-Eur"
|
n.name = "PyPSA-Eur"
|
||||||
|
|
||||||
n.set_snapshots(pd.date_range(freq="h", **config["snapshots"]))
|
n.set_snapshots(pd.date_range(freq="h", **snapshots))
|
||||||
n.madd("Carrier", ["AC", "DC"])
|
n.madd("Carrier", ["AC", "DC"])
|
||||||
|
|
||||||
n.import_components_from_dataframe(buses, "Bus")
|
n.import_components_from_dataframe(buses, "Bus")
|
||||||
|
@ -146,8 +146,10 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
configure_logging(snakemake)
|
configure_logging(snakemake)
|
||||||
|
|
||||||
|
snapshots = snakemake.params.snapshots
|
||||||
|
|
||||||
n = pypsa.Network(snakemake.input.base_network)
|
n = pypsa.Network(snakemake.input.base_network)
|
||||||
time = pd.date_range(freq="h", **snakemake.config["snapshots"])
|
time = pd.date_range(freq="h", **snapshots)
|
||||||
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=time)
|
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=time)
|
||||||
|
|
||||||
da = calculate_line_rating(n, cutout)
|
da = calculate_line_rating(n, cutout)
|
||||||
|
@ -210,6 +210,7 @@ if __name__ == "__main__":
|
|||||||
resource = params["resource"] # pv panel params / wind turbine params
|
resource = params["resource"] # pv panel params / wind turbine params
|
||||||
correction_factor = params.get("correction_factor", 1.0)
|
correction_factor = params.get("correction_factor", 1.0)
|
||||||
capacity_per_sqkm = params["capacity_per_sqkm"]
|
capacity_per_sqkm = params["capacity_per_sqkm"]
|
||||||
|
snapshots = snakemake.params.snapshots
|
||||||
|
|
||||||
if correction_factor != 1.0:
|
if correction_factor != 1.0:
|
||||||
logger.info(f"correction_factor is set as {correction_factor}")
|
logger.info(f"correction_factor is set as {correction_factor}")
|
||||||
@ -219,7 +220,7 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
client = None
|
client = None
|
||||||
|
|
||||||
sns = pd.date_range(freq="h", **snakemake.config["snapshots"])
|
sns = pd.date_range(freq="h", **snapshots)
|
||||||
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=sns)
|
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=sns)
|
||||||
regions = gpd.read_file(snakemake.input.regions)
|
regions = gpd.read_file(snakemake.input.regions)
|
||||||
assert not regions.empty, (
|
assert not regions.empty, (
|
||||||
|
@ -63,7 +63,7 @@ import re
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pypsa
|
import pypsa
|
||||||
from _helpers import configure_logging
|
from _helpers import configure_logging, find_opt, get_opt
|
||||||
from add_electricity import load_costs, update_transmission_costs
|
from add_electricity import load_costs, update_transmission_costs
|
||||||
from pypsa.descriptors import expand_series
|
from pypsa.descriptors import expand_series
|
||||||
|
|
||||||
@ -296,42 +296,42 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
set_line_s_max_pu(n, snakemake.params.lines["s_max_pu"])
|
set_line_s_max_pu(n, snakemake.params.lines["s_max_pu"])
|
||||||
|
|
||||||
for o in opts:
|
# temporal averaging
|
||||||
m = re.match(r"^\d+h$", o, re.IGNORECASE)
|
nhours_config = snakemake.params.snapshots.get("resolution", False)
|
||||||
if m is not None:
|
nhours_wildcard = get_opt(opts, r"^\d+h$")
|
||||||
n = average_every_nhours(n, m.group(0))
|
nhours = nhours_wildcard or nhours_config
|
||||||
break
|
if nhours:
|
||||||
|
n = average_every_nhours(n, nhours)
|
||||||
|
|
||||||
for o in opts:
|
# segments with package tsam
|
||||||
m = re.match(r"^\d+seg$", o, re.IGNORECASE)
|
time_seg_config = snakemake.params.snapshots.get("segmentation", False)
|
||||||
if m is not None:
|
time_seg_wildcard = get_opt(opts, r"^\d+seg$")
|
||||||
|
time_seg = time_seg_wildcard or time_seg_config
|
||||||
|
if time_seg:
|
||||||
solver_name = snakemake.config["solving"]["solver"]["name"]
|
solver_name = snakemake.config["solving"]["solver"]["name"]
|
||||||
n = apply_time_segmentation(n, m.group(0)[:-3], solver_name)
|
n = apply_time_segmentation(n, time_seg.replace("seg", ""), solver_name)
|
||||||
break
|
|
||||||
|
|
||||||
for o in opts:
|
Co2L_config = snakemake.params.co2limit_enable
|
||||||
if "Co2L" in o:
|
Co2L_wildcard, co2limit_wildcard = find_opt(opts, "Co2L")
|
||||||
m = re.findall("[0-9]*\.?[0-9]+$", o)
|
if Co2L_wildcard or Co2L_config:
|
||||||
if len(m) > 0:
|
if co2limit_wildcard is not None:
|
||||||
co2limit = float(m[0]) * snakemake.params.co2base
|
co2limit = co2limit_wildcard * snakemake.params.co2base
|
||||||
add_co2limit(n, co2limit, Nyears)
|
add_co2limit(n, co2limit, Nyears)
|
||||||
logger.info("Setting CO2 limit according to wildcard value.")
|
logger.info("Setting CO2 limit according to wildcard value.")
|
||||||
else:
|
else:
|
||||||
add_co2limit(n, snakemake.params.co2limit, Nyears)
|
add_co2limit(n, snakemake.params.co2limit, Nyears)
|
||||||
logger.info("Setting CO2 limit according to config value.")
|
logger.info("Setting CO2 limit according to config value.")
|
||||||
break
|
|
||||||
|
|
||||||
for o in opts:
|
CH4L_config = snakemake.params.gaslimit_enable
|
||||||
if "CH4L" in o:
|
CH4L_wildcard, gaslimit_wildcard = find_opt(opts, "CH4L")
|
||||||
m = re.findall("[0-9]*\.?[0-9]+$", o)
|
if CH4L_wildcard or CH4L_config:
|
||||||
if len(m) > 0:
|
if gaslimit_wildcard is not None:
|
||||||
limit = float(m[0]) * 1e6
|
gaslimit = gaslimit_wildcard * 1e6
|
||||||
add_gaslimit(n, limit, Nyears)
|
add_gaslimit(n, gaslimit, Nyears)
|
||||||
logger.info("Setting gas usage limit according to wildcard value.")
|
logger.info("Setting gas usage limit according to wildcard value.")
|
||||||
else:
|
else:
|
||||||
add_gaslimit(n, snakemake.params.gaslimit, Nyears)
|
add_gaslimit(n, snakemake.params.gaslimit, Nyears)
|
||||||
logger.info("Setting gas usage limit according to config value.")
|
logger.info("Setting gas usage limit according to config value.")
|
||||||
break
|
|
||||||
|
|
||||||
for o in opts:
|
for o in opts:
|
||||||
if "+" not in o:
|
if "+" not in o:
|
||||||
@ -352,21 +352,26 @@ if __name__ == "__main__":
|
|||||||
sel = c.df.carrier.str.contains(carrier)
|
sel = c.df.carrier.str.contains(carrier)
|
||||||
c.df.loc[sel, attr] *= factor
|
c.df.loc[sel, attr] *= factor
|
||||||
|
|
||||||
for o in opts:
|
emission_prices = snakemake.params.costs["emission_prices"]
|
||||||
if "Ept" in o:
|
Ept_config = emission_prices.get("co2_monthly_prices", False)
|
||||||
|
Ept_wildcard = "Ept" in opts
|
||||||
|
Ep_config = emission_prices.get("enable", False)
|
||||||
|
Ep_wildcard, co2_wildcard = find_opt(opts, "Ep")
|
||||||
|
|
||||||
|
if Ept_wildcard or Ept_config:
|
||||||
logger.info(
|
logger.info(
|
||||||
"Setting time dependent emission prices according spot market price"
|
"Setting time dependent emission prices according spot market price"
|
||||||
)
|
)
|
||||||
add_dynamic_emission_prices(n)
|
add_dynamic_emission_prices(n)
|
||||||
elif "Ep" in o:
|
elif Ep_wildcard or Ep_config:
|
||||||
m = re.findall("[0-9]*\.?[0-9]+$", o)
|
if co2_wildcard is not None:
|
||||||
if len(m) > 0:
|
logger.info("Setting CO2 prices according to wildcard value.")
|
||||||
logger.info("Setting emission prices according to wildcard value.")
|
add_emission_prices(n, dict(co2=co2_wildcard))
|
||||||
add_emission_prices(n, dict(co2=float(m[0])))
|
|
||||||
else:
|
else:
|
||||||
logger.info("Setting emission prices according to config value.")
|
logger.info("Setting CO2 prices according to config value.")
|
||||||
add_emission_prices(n, snakemake.params.costs["emission_prices"])
|
add_emission_prices(
|
||||||
break
|
n, dict(co2=snakemake.params.costs["emission_prices"]["co2"])
|
||||||
|
)
|
||||||
|
|
||||||
ll_type, factor = snakemake.wildcards.ll[0], snakemake.wildcards.ll[1:]
|
ll_type, factor = snakemake.wildcards.ll[0], snakemake.wildcards.ll[1:]
|
||||||
set_transmission_limit(n, ll_type, factor, costs, Nyears)
|
set_transmission_limit(n, ll_type, factor, costs, Nyears)
|
||||||
@ -379,10 +384,12 @@ if __name__ == "__main__":
|
|||||||
p_nom_max_ext=snakemake.params.links.get("max_extension", np.inf),
|
p_nom_max_ext=snakemake.params.links.get("max_extension", np.inf),
|
||||||
)
|
)
|
||||||
|
|
||||||
if "ATK" in opts:
|
autarky_config = snakemake.params.autarky
|
||||||
enforce_autarky(n)
|
if "ATK" in opts or autarky_config.get("enable", False):
|
||||||
elif "ATKc" in opts:
|
only_crossborder = False
|
||||||
enforce_autarky(n, only_crossborder=True)
|
if "ATKc" in opts or autarky_config.get("by_country", False):
|
||||||
|
only_crossborder = True
|
||||||
|
enforce_autarky(n, only_crossborder=only_crossborder)
|
||||||
|
|
||||||
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
|
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
|
||||||
n.export_to_netcdf(snakemake.output[0])
|
n.export_to_netcdf(snakemake.output[0])
|
||||||
|
@ -37,7 +37,7 @@ import pandas as pd
|
|||||||
import pypsa
|
import pypsa
|
||||||
import xarray as xr
|
import xarray as xr
|
||||||
from _benchmark import memory_logger
|
from _benchmark import memory_logger
|
||||||
from _helpers import configure_logging, update_config_with_sector_opts
|
from _helpers import configure_logging, get_opt, update_config_with_sector_opts
|
||||||
from pypsa.descriptors import get_activity_mask
|
from pypsa.descriptors import get_activity_mask
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -806,18 +806,30 @@ def extra_functionality(n, snapshots):
|
|||||||
"""
|
"""
|
||||||
opts = n.opts
|
opts = n.opts
|
||||||
config = n.config
|
config = n.config
|
||||||
if "BAU" in opts and n.generators.p_nom_extendable.any():
|
constraints = config["solving"].get("constraints", {})
|
||||||
|
if (
|
||||||
|
"BAU" in opts or constraints.get("BAU", False)
|
||||||
|
) and n.generators.p_nom_extendable.any():
|
||||||
add_BAU_constraints(n, config)
|
add_BAU_constraints(n, config)
|
||||||
if "SAFE" in opts and n.generators.p_nom_extendable.any():
|
if (
|
||||||
|
"SAFE" in opts or constraints.get("SAFE", False)
|
||||||
|
) and n.generators.p_nom_extendable.any():
|
||||||
add_SAFE_constraints(n, config)
|
add_SAFE_constraints(n, config)
|
||||||
if "CCL" in opts and n.generators.p_nom_extendable.any():
|
if (
|
||||||
|
"CCL" in opts or constraints.get("CCL", False)
|
||||||
|
) and n.generators.p_nom_extendable.any():
|
||||||
add_CCL_constraints(n, config)
|
add_CCL_constraints(n, config)
|
||||||
|
|
||||||
reserve = config["electricity"].get("operational_reserve", {})
|
reserve = config["electricity"].get("operational_reserve", {})
|
||||||
if reserve.get("activate"):
|
if reserve.get("activate"):
|
||||||
add_operational_reserve_margin(n, snapshots, config)
|
add_operational_reserve_margin(n, snapshots, config)
|
||||||
for o in opts:
|
|
||||||
if "EQ" in o:
|
EQ_config = constraints.get("EQ", False)
|
||||||
add_EQ_constraints(n, o)
|
EQ_wildcard = get_opt(opts, r"^EQ+[0-9]*\.?[0-9]+(c|)")
|
||||||
|
EQ_o = EQ_wildcard or EQ_config
|
||||||
|
if EQ_o:
|
||||||
|
add_EQ_constraints(n, EQ_o.replace("EQ", ""))
|
||||||
|
|
||||||
add_battery_constraints(n)
|
add_battery_constraints(n)
|
||||||
add_lossy_bidirectional_link_constraints(n)
|
add_lossy_bidirectional_link_constraints(n)
|
||||||
add_pipe_retrofit_constraint(n)
|
add_pipe_retrofit_constraint(n)
|
||||||
|
Loading…
Reference in New Issue
Block a user