move uc assigment to add_electricity
make code backwards-compatible
This commit is contained in:
parent
cc6bae282f
commit
519a4f2a2a
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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(
|
||||
|
@ -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 {}
|
||||
|
Loading…
Reference in New Issue
Block a user