move uc assigment to add_electricity

make code backwards-compatible
This commit is contained in:
Fabian 2023-06-29 14:50:41 +02:00
parent cc6bae282f
commit 519a4f2a2a
6 changed files with 48 additions and 37 deletions

View File

@ -254,6 +254,8 @@ renewable:
clip_min_inflow: 1.0
conventional:
unit_commitment: false
dynamic_fuel_price: false
nuclear:
p_max_pu: "data/nuclear_p_max_pu.csv" # float of file name
@ -345,8 +347,6 @@ solar_thermal:
# only relevant for foresight = myopic or perfect
existing_capacities:
unit_commitment: true # if unit commitment (UC) for conventional power plants is used
# UC is only applied to extendable plants if linearized UC is used
grouping_years_power: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020, 2025, 2030]
grouping_years_heat: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2019] # these should not extend 2020
threshold_capacity: 10

View File

@ -243,6 +243,8 @@ renewable:
clip_min_inflow: 1.0
conventional:
unit_commitment: true
dynamic_fuel_price: true
nuclear:
p_max_pu: "data/nuclear_p_max_pu.csv" # float of file name

View File

@ -296,7 +296,7 @@ rule add_electricity:
countries=config["countries"],
renewable=config["renewable"],
electricity=config["electricity"],
conventional=config.get("conventional", {}),
conventional=config["conventional"],
costs=config["costs"],
input:
**{
@ -306,6 +306,7 @@ rule add_electricity:
**{
f"conventional_{carrier}_{attr}": fn
for carrier, d in config.get("conventional", {None: {}}).items()
if carrier in config["electricity"]["conventional_carriers"]
for attr, fn in d.items()
if str(fn).startswith("data/")
},
@ -315,6 +316,7 @@ rule add_electricity:
powerplants=RESOURCES + "powerplants.csv",
hydro_capacities=ancient("data/bundle/hydro_capacities.csv"),
geth_hydro_capacities="data/geth2015_hydro_capacities.csv",
unit_commitment="data/unit_commitment.csv",
fuel_price="data/validation/monthly_fuel_price.csv",
load=RESOURCES + "load.csv",
nuts3_shapes=RESOURCES + "nuts3_shapes.geojson",

View File

@ -12,7 +12,6 @@ rule solve_network:
"co2_sequestration_potential", 200
),
input:
unit_commitment_params="data/unit_commitment.csv",
network=RESOURCES + "networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc",
output:
network=RESULTS + "networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc",

View File

@ -366,12 +366,13 @@ def attach_wind_and_solar(
def attach_conventional_generators(
n,
costs,
fuel_price,
ppl,
conventional_carriers,
extendable_carriers,
conventional_params,
conventional_inputs,
unit_commitment=None,
fuel_price=None,
):
carriers = set(conventional_carriers) | set(extendable_carriers["Generator"])
_add_missing_carriers_from_costs(n, costs, carriers)
@ -383,19 +384,30 @@ def attach_conventional_generators(
)
ppl["efficiency"] = ppl.efficiency.fillna(ppl.efficiency_r)
fuel_price = fuel_price.assign(OCGT=fuel_price["gas"], CCGT=fuel_price["gas"]).drop(
"gas", axis=1
)
fuel_price = fuel_price.reindex(ppl.carrier, axis=1)
fuel_price.fillna(costs.fuel, inplace=True)
fuel_price.columns = ppl.index
marginal_cost = (fuel_price.div(ppl.efficiency)).add(ppl.carrier.map(costs.VOM))
if unit_commitment is not None:
committable_attrs = ppl.carrier.isin(unit_commitment).to_frame('committable')
for attr in unit_commitment.index:
default = pypsa.components.component_attrs['Generator'].default[attr]
committable_attrs[attr] = ppl.carrier.map(unit_commitment.loc[attr]).fillna(default)
else:
committable_attrs = {}
logger.info(
"Adding {} generators with capacities [GW] \n{}".format(
len(ppl), ppl.groupby("carrier").p_nom.sum().div(1e3).round(2)
)
)
if fuel_price is not None:
fuel_price = (fuel_price.assign(OCGT=fuel_price['gas'],
CCGT=fuel_price['gas'])
.drop("gas", axis=1))
missing_carriers = list(carriers - set(fuel_price))
fuel_price = fuel_price.assign(**costs.fuel[missing_carriers])
fuel_price = fuel_price.reindex(ppl.carrier, axis=1)
fuel_price.columns = ppl.index
marginal_cost = fuel_price.div(ppl.efficiency).add(ppl.carrier.map(costs.VOM))
else:
marginal_cost = ppl.carrier.map(costs.VOM) + ppl.carrier.map(costs.fuel) / ppl.efficiency
# Define generators using modified ppl DataFrame
caps = ppl.groupby("carrier").p_nom.sum().div(1e3).round(2)
logger.info(f"Adding {len(ppl)} generators with capacities [GW] \n{caps}")
n.madd(
"Generator",
@ -410,9 +422,10 @@ def attach_conventional_generators(
capital_cost=ppl.capital_cost,
build_year=ppl.datein.fillna(0).astype(int),
lifetime=(ppl.dateout - ppl.datein).fillna(np.inf),
**committable_attrs
)
for carrier in conventional_params:
for carrier in set(conventional_params) & carriers:
# Generators with technology affected
idx = n.generators.query("carrier == @carrier").index
@ -752,18 +765,28 @@ if __name__ == "__main__":
k: v for k, v in snakemake.input.items() if k.startswith("conventional_")
}
m_fuel_price = pd.read_csv(snakemake.input.fuel_price, index_col=[0], header=[0])
m_fuel_price.index = pd.date_range(start="2019-01-01", end="2019-12-01", freq="MS")
fuel_price = m_fuel_price.reindex(n.snapshots).fillna(method="ffill")
if params.conventional["unit_commitment"]:
unit_commitment = pd.read_csv(snakemake.input.unit_commitment, index_col=0)
else:
unit_commitment = None
if params.conventional["dynamic_fuel_price"]:
monthly_fuel_price = pd.read_csv(snakemake.input.fuel_price, index_col=0, header=0)
monthly_fuel_price.index = pd.date_range(start=n.snapshots[0], end=n.snapshots[-1], freq='MS')
fuel_price = monthly_fuel_price.reindex(n.snapshots).fillna(method="ffill")
else:
fuel_price = None
attach_conventional_generators(
n,
costs,
fuel_price,
ppl,
conventional_carriers,
extendable_carriers,
params.conventional,
conventional_inputs,
unit_commitment=unit_commitment,
fuel_price=fuel_price,
)
attach_wind_and_solar(

View File

@ -149,8 +149,6 @@ def prepare_network(
planning_horizons=None,
co2_sequestration_potential=None,
):
if snakemake.config["existing_capacities"]["unit_commitment"]:
add_unit_commitment(n, snakemake.input.unit_commitment_params)
if "clip_p_max_pu" in solve_opts:
for df in (
@ -600,19 +598,6 @@ def extra_functionality(n, snapshots):
add_pipe_retrofit_constraint(n)
def add_unit_commitment(n, fn):
"""
Add unit commitment.
"""
c = "Generator"
uc_data = pd.read_csv(fn, index_col=0)
n.df(c).loc[n.df(c).carrier.isin(uc_data.columns), "committable"] = True
for attr in uc_data.index:
n.df(c)[attr].update(n.df(c)["carrier"].map(uc_data.loc[attr]).dropna())
gen_i = n.df(c).query("carrier in @uc_data.columns").index
n.df(c).loc[gen_i, "committable"] = True
def solve_network(n, config, solving, opts="", **kwargs):
set_of_options = solving["solver"]["options"]
solver_options = solving["solver_options"][set_of_options] if set_of_options else {}