diff --git a/rules/supply_curves.smk b/rules/supply_curves.smk index 194711e..dbe5ac9 100644 --- a/rules/supply_curves.smk +++ b/rules/supply_curves.smk @@ -12,6 +12,20 @@ def _process_label_for_product(product): return route_label_for_product(config, product) +def _local_demand_input(wildcards): + """Local electricity demand data, only when the 'reserved' scenario needs it. + + The 'reserved' scenario derives its capacity-reservation target from this + file unless reserve_local_demand_mw is set explicitly in config; the + 'unreserved' and 'allocated_share' scenarios never read it. + """ + needs_demand = ( + wildcards.scenario == "reserved" + and config.get("reserve_local_demand_mw", 0) <= 0 + ) + return "data/un_enerdata_demand_2050_final.csv" if needs_demand else [] + + def _product_uses_renewables(product): """Check if a product's stage group uses renewable_electricity. @@ -86,7 +100,7 @@ rule prepare_regional_network: ), renewables="resources/renewables_clustered.nc", tech_costs="resources/technology_data/costs_{cost_year}.csv", - local_demand="data/un_enerdata_demand_2050_final.csv", + local_demand=_local_demand_input, wacc="resources/wacc-clustered.csv", labour_cost="resources/labour_cost_clustered.csv", output: @@ -118,7 +132,7 @@ if config["enable"].get("run_supply_chain", True): rule calculate_regional_lcox: input: base_network="resources/networks/base_{cost_year}_{region}_{wacc}_{product}_{scenario}.nc", - local_demand="data/un_enerdata_demand_2050_final.csv", + local_demand=_local_demand_input, output: # Internal cache keyed by route_label for reuse; only products matter for supply curves results="resources/lco-{product}/cost_year~{cost_year}/wacc~{wacc}/{region}_{scenario}/results_{product_demand_mt}.csv", diff --git a/rules/trade_model.smk b/rules/trade_model.smk index 65516e8..018c092 100644 --- a/rules/trade_model.smk +++ b/rules/trade_model.smk @@ -23,7 +23,13 @@ rule model_trade: ), trade_options="resources/trade_opt_chokepoints.csv", bus_locations="data/bus_locations.csv", - demand="data/un_enerdata_demand_2050_final.csv", + # Only the hydrogen final product reads this file (model_trade.py); + # the active steel chain gets its demand from steel_demand instead. + demand=( + "data/un_enerdata_demand_2050_final.csv" + if config["trade_chains"]["final_product"] == "hydrogen" + else [] + ), steel_demand="resources/steel_demand_clustered_{cost_year}.csv", iron_ore="resources/ironore_production_clustered.csv", grid_potential="data/grid_potential_custom.csv", diff --git a/workflow/scripts/calculate_lcox.py b/workflow/scripts/calculate_lcox.py index 47f4eb2..3dda176 100644 --- a/workflow/scripts/calculate_lcox.py +++ b/workflow/scripts/calculate_lcox.py @@ -42,7 +42,14 @@ def load_demands_for_region(region, config): Returns dict with: - local_el_demand_mwh: MWh/year (for renewable constraint calculation) + + local_demand is only provided as an input for the 'reserved' scenario + (see _local_demand_input in rules/supply_curves.smk); other scenarios + don't use it and get 0 here. """ + if not snakemake.input.local_demand: + return {"local_el_demand_mwh": 0} + # Load local electricity demand (for renewable constraint calculation) try: local_df = pd.read_csv(snakemake.input.local_demand)