From 012de6c1abc84cf6f6a4c475abb2c506a490f063 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Wed, 14 Aug 2024 08:41:07 -0700 Subject: [PATCH 01/17] sync to upstream --- workflow/config/config.api.yaml | 4 + workflow/config/config.cluster.yaml | 29 + workflow/config/config.common.yaml | 138 ++ workflow/config/config.default.yaml | 295 ++++ workflow/config/config.egs.yaml | 284 ++++ workflow/config/config.mod_default.yaml | 284 ++++ workflow/config/config.plotting.yaml | 122 ++ workflow/config/config.tutorial.yaml | 287 ++++ workflow/config/config.validation.yaml | 284 ++++ workflow/config/policy_constraints/.DS_Store | Bin 0 -> 6148 bytes .../policy_constraints/SAFE_regional_prm.csv | 2 + .../policy_constraints/agg_p_nom_minmax.csv | 2 + .../portfolio_standards.csv | 2 + .../policy_constraints/reeds/ces_fraction.csv | 17 + .../reeds/offshore_req_30by30.csv | 15 + .../reeds/offshore_req_default.csv | 10 + .../policy_constraints/reeds/prm_annual.csv | 311 ++++ .../policy_constraints/reeds/rggi_states.csv | 12 + .../policy_constraints/reeds/rggicon.csv | 41 + .../policy_constraints/reeds/rps_fraction.csv | 1307 +++++++++++++++++ .../reeds/storage_mandates.csv | 276 ++++ .../regional_Co2_limits.csv | 54 + .../transmission_interface_limits.csv | 4 + 23 files changed, 3780 insertions(+) create mode 100644 workflow/config/config.api.yaml create mode 100644 workflow/config/config.cluster.yaml create mode 100644 workflow/config/config.common.yaml create mode 100644 workflow/config/config.default.yaml create mode 100644 workflow/config/config.egs.yaml create mode 100644 workflow/config/config.mod_default.yaml create mode 100644 workflow/config/config.plotting.yaml create mode 100644 workflow/config/config.tutorial.yaml create mode 100644 workflow/config/config.validation.yaml create mode 100644 workflow/config/policy_constraints/.DS_Store create mode 100644 workflow/config/policy_constraints/SAFE_regional_prm.csv create mode 100644 workflow/config/policy_constraints/agg_p_nom_minmax.csv create mode 100644 workflow/config/policy_constraints/portfolio_standards.csv create mode 100644 workflow/config/policy_constraints/reeds/ces_fraction.csv create mode 100644 workflow/config/policy_constraints/reeds/offshore_req_30by30.csv create mode 100644 workflow/config/policy_constraints/reeds/offshore_req_default.csv create mode 100644 workflow/config/policy_constraints/reeds/prm_annual.csv create mode 100644 workflow/config/policy_constraints/reeds/rggi_states.csv create mode 100644 workflow/config/policy_constraints/reeds/rggicon.csv create mode 100644 workflow/config/policy_constraints/reeds/rps_fraction.csv create mode 100644 workflow/config/policy_constraints/reeds/storage_mandates.csv create mode 100644 workflow/config/policy_constraints/regional_Co2_limits.csv create mode 100644 workflow/config/policy_constraints/transmission_interface_limits.csv diff --git a/workflow/config/config.api.yaml b/workflow/config/config.api.yaml new file mode 100644 index 00000000..eb7afdee --- /dev/null +++ b/workflow/config/config.api.yaml @@ -0,0 +1,4 @@ +# holds user api keys + +api: + eia: kWdnW4WaIeeq2bsihF75w06C1FKiavVVg6he0CT7 diff --git a/workflow/config/config.cluster.yaml b/workflow/config/config.cluster.yaml new file mode 100644 index 00000000..5c44ff24 --- /dev/null +++ b/workflow/config/config.cluster.yaml @@ -0,0 +1,29 @@ +__default__: + account: horne + partition: serc + email: m.j.aljubran@gmail.com + walltime: 00:30:00 # time limit for each job + cpus_per_task: 1 # number of cores per job + chdir: $GROUP_SCRATCH/aljubrmj/framework_4/hl_markets/pypsa-usa/workflow/ + output: logs/{rule}/log-%j.out + error: logs/{rule}/errlog-%j.err + + + +build_renewable_profiles: + walltime: 02:00:00 + +add_electricity: + walltime: 02:00:00 + +simplify_network: + walltime: 02:00:00 + +cluster_network: + walltime: 02:00:00 + +solve_network: + walltime: 06:00:00 + +solve_network_validation: + walltime: 06:00:00 diff --git a/workflow/config/config.common.yaml b/workflow/config/config.common.yaml new file mode 100644 index 00000000..a39e8e9a --- /dev/null +++ b/workflow/config/config.common.yaml @@ -0,0 +1,138 @@ + +countries: [US] + +network_configuration: "pypsa-usa" # "pypsa-usa" or "ads2032" + + +# docs : +renewable: + onwind: + cutout: era5_2019 + resource: + method: wind + turbine: Vestas_V112_3MW + add_cutout_windspeed: true + capacity_per_sqkm: 3 # conservative, ScholzPhd Tab 4.3.1: 10MW/km^2 + correction_factor: 1 # 0.93 + corine: + #all keys labeled corrine are actually copernicus codes. Using the name corrine bc using the pypsa-eur convention: https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf + grid_codes: [20, 30, 40, 60, 100, 112, 113, 114, 115] + distance: 10 #buffer from distance_grid_codes that are to be excluded + distance_grid_codes: [50] + natura: true + cec: true + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + offwind: + cutout: era5_2019 + resource: + method: wind + turbine: NREL_ReferenceTurbine_2020ATB_5.5MW + # add_cutout_windspeed: true + capacity_per_sqkm: 3 # 2021–2022 Transmission Plan, CAISO + correction_factor: 1 # 0.8855 # proxy for wake losses, from 10.1016/j.energy.2018.08.153 + corine: + grid_codes: [80, 200] #page 28 of https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf + natura: true + boem_screen: true + max_depth: 60 # meters, ref https://www.nrel.gov/docs/fy16osti/66599.pdf + min_shore_distance: 22000 # meters + max_shore_distance: 65000 # meters + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + offwind_floating: + cutout: era5_2019 + resource: + method: wind + turbine: NREL_ReferenceTurbine_2020ATB_15MW_offshore + add_cutout_windspeed: true + capacity_per_sqkm: 3 # 2021–2022 Transmission Plan, CAISO + correction_factor: 1 # 0.8855 # proxy for wake losses, from 10.1016/j.energy.2018.08.153 + corine: + grid_codes: [80, 200] #page 28 of https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf + natura: true + boem_screen: true + min_depth: 60 # meters, ref https://www.nrel.gov/docs/fy16osti/66599.pdf + max_depth: 1300 # meters, ref https://www.nrel.gov/docs/fy22osti/83650.pdf + min_shore_distance: 22000 # meters + max_shore_distance: 65000 # meters + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + solar: + cutout: era5_2019 + resource: + method: pv + panel: CSi + orientation: latitude_optimal # will lead into optimal + capacity_per_sqkm: 4.6 # From 1.7 to 4.6 addresses issue #361 - TODO revisit this assumption + correction_factor: 1 # 0.854337 + corine: + grid_codes: [20, 30, 40, 60, 90, 100] #see above for codes + natura: true + cec: true + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + hydro: + cutout: era5_2019 + carriers: [ror, PHS, hydro] + PHS_max_hours: 6 + resource: + method: hydro + hydrobasins: resources/hybas_na_lev06_v1c.shp + flowspeed: 1.0 # m/s + hydro_max_hours: "energy_capacity_totals_by_country" # not active + clip_min_inflow: 1.0 + extendable: true + normalization: + method: hydro_capacities + year: 2013 + multiplier: 1.1 # multiplier applied after the normalization of the hydro production; default 1.0 + + +# docs : +atlite: + default_cutout: era5_2019 + nprocesses: 8 + show_progress: false # false saves time + cutouts: + era5_2019: + module: era5 # in priority order + time: ['2019', '2019'] + interconnects: + western: + x: [-126, -99] + y: [27, 50] + dx: 0.3 + dy: 0.3 + eastern: + x: [-109, -65] + y: [23, 50] + dx: 0.3 + dy: 0.3 + texas: + x: [-110, -90] + y: [24, 37] + dx: 0.3 + dy: 0.3 + usa: + x: [-126, -65] + y: [23, 50] + dx: 0.3 + dy: 0.3 + + +# docs : +offshore_shape: + use: eez #options are ca_osw, eez + +offshore_network: + enable: true # set to true to enable offshore network + bus_spacing: 25000 # km + +costs: + itc_modifier: {} + ptc_modifier: {} \ No newline at end of file diff --git a/workflow/config/config.default.yaml b/workflow/config/config.default.yaml new file mode 100644 index 00000000..877e0dd6 --- /dev/null +++ b/workflow/config/config.default.yaml @@ -0,0 +1,295 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Default" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [western] #"usa|texas|western|eastern" + clusters: [40] + opts: [REM-1000SEG] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: + - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2020-01-01" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 + co2limit_enable: false + co2base: 226.86e+6 + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired + StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] + Store: [] + Link: [] + + demand: + profile: eia # efs, eia + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true # Imposes ITLs over AC Lines + transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs + + +# docs : +links: + p_max_pu: 1.0 + p_nom_max: .inf + max_extension: 1000.0e+3 + + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + ptc_modifier: + onwind: 18.2547 + geothermal: 18.2547 + biomass: 18.2547 + itc_modifier: + solar: 0.3 + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 4 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 8 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 8 + cplex-default: + threads: 4 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "12:00:00" + + +# docs : +custom_files: + activate: false + files_path: '' + network_name: '' \ No newline at end of file diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml new file mode 100644 index 00000000..0a510673 --- /dev/null +++ b/workflow/config/config.egs.yaml @@ -0,0 +1,284 @@ +# PyPSA-USA Default Configuration File + +run: + name: "EGS" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [western] #"usa|texas|western|eastern" + clusters: [33] + opts: [REM-2000SEG] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: [2030, 2040, 2050] + # - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2019-12-31" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro, EGS] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 # 0.8 * 1.841e+9 + co2limit_enable: false # For sector coupled studies + co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false # For sector coupled studies + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, EGS, OCGT, CCGT, coal, CCGT-95CCS] #offwind, offwind_floating, maybe include CCGT-CCS + StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours)] + Store: [] + Link: [] + + demand: + profile: efs # efs, eia + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true + transport_model : true + +# docs : +links: + p_max_pu: 0.7 + p_nom_max: .inf + max_extension: 1000.0e+3 + + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 24 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 24 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 24 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 24 + cplex-default: + threads: 24 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "24:00:00" + + +# docs : +custom_files: + activate: false + files_path: '' + network_name: '' \ No newline at end of file diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml new file mode 100644 index 00000000..b9267325 --- /dev/null +++ b/workflow/config/config.mod_default.yaml @@ -0,0 +1,284 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Default" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [texas] #"usa|texas|western|eastern" + clusters: [8] + opts: [REM-2000SEG] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: [2030, 2040, 2050] + # - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2019-12-31" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 # 0.8 * 1.841e+9 + co2limit_enable: false # For sector coupled studies + co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false # For sector coupled studies + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR] #offwind, offwind_floating, maybe include CCGT-CCS + StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage] # [Xhr-battery-storage (2-10 hours)] + Store: [] + Link: [] + + demand: + profile: efs # efs, eia + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true + transport_model : true + +# docs : +links: + p_max_pu: 0.7 + p_nom_max: .inf + max_extension: 1000.0e+3 + + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 24 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 24 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 24 + cplex-default: + threads: 24 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "24:00:00" + + +# docs : +custom_files: + activate: false + files_path: '' + network_name: '' \ No newline at end of file diff --git a/workflow/config/config.plotting.yaml b/workflow/config/config.plotting.yaml new file mode 100644 index 00000000..1332b9a2 --- /dev/null +++ b/workflow/config/config.plotting.yaml @@ -0,0 +1,122 @@ +plotting: + costs_max: 800 + costs_threshold: 1 + + energy_max: 15000. + energy_min: -10000. + energy_threshold: 50. + + # vre_techs: ["onwind","offwind_floating", "offwind-ac", "offwind-dc", "solar", "ror"] + # conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"] + # storage_techs: ["hydro+PHS", "battery", "H2"] + # load_carriers: ["AC load"] + # AC_carriers: ["AC line", "AC transformer"] + # link_carriers: ["DC line", "Converter AC-DC"] + tech_colors: + "onwind": "#235ebc" + "wind": "#235ebc" + "onshore wind": "#235ebc" + 'offwind': "#dd6895" + 'offshore wind': "#6895dd" + 'offwind-ac': "#6895dd" + 'offshore wind ac': "#6895dd" + 'offwind-dc': "#74c6f2" + 'offshore wind dc': "#74c6f2" + 'offwind_floating': "#11a1c1" + "hydro": "#08ad97" + "hydro+PHS": "#08ad97" + "PHS": "#08ad97" + "hydro reservoir": "#08ad97" + 'hydroelectricity': '#08ad97' + "ror": "#4adbc8" + "run of river": "#4adbc8" + 'solar': "#f9d002" + 'solar PV': "#f9d002" + 'solar thermal': '#ffef60' + 'biomass': '#0c6013' + 'solid biomass': '#06540d' + 'biogas': '#23932d' + 'waste': '#68896b' + 'geothermal': '#ba91b1' + 'EGS': '#DAA520' + "OCGT": "#d35050" + "gas": "#d35050" + "ng": "#d35050" + "natural gas": "#d35050" + "CCGT": "#b20101" + "nuclear": "#ff9000" + "coal": "#707070" + "lignite": "#9e5a01" + "oil": "#262626" + "H2": "#ea048a" + "hydrogen storage": "#ea048a" + "battery": "#b8ea04" + "2hr_battery_storage": "#aee000" + "4hr_battery_storage": "#a4d600" + "6hr_battery_storage": "#9acc00" + "8hr_battery_storage": "#90c200" + "10hr_battery_storage": "#86b800" + "Electric load": "#f9d002" + "electricity": "#f9d002" + "lines": "#70af1d" + "transmission lines": "#70af1d" + "AC-AC": "#70af1d" + "AC line": "#70af1d" + "AC": "#70af1d" + "links": "#8a1caf" + "HVDC links": "#8a1caf" + "DC-DC": "#8a1caf" + "DC link": "#8a1caf" + "DC": "#8a1caf" + "Load": "#2ad55f" + "res-elec": "#f9d002" + "res-heat": "#E79CA2" + "res-cool": "#9CE7E2" + "com-elec": "#f9d002" + "com-heat": "#E79CA2" + "com-cool": "#9CE7E2" + "ind-elec": "#f9d002" + "ind-heat": "#E79CA2" + "trn-elec": "#f9d002" + "coal-95CCS": "#4b4b4b" + "coal-99CCS": "#2e2e2e" + "SMR": "#ff5733" + "CCGT-95CCS": "#800000" + "8hr_PHS": "#069686" + "10hr_PHS": "#058a79" + "12hr_PHS": "#047d6c" + "8hr_PHS_discharger": "#069686" + "10hr_PHS_discharger": "#058a79" + "12hr_PHS_discharger": "#047d6c" + "8hr_PHS_charger": "#069686" + "10hr_PHS_charger": "#058a79" + "12hr_PHS_charger": "#047d6c" + + nice_names: + OCGT: "Open-Cycle Gas" + CCGT: "Combined-Cycle Gas" + offwind: "Fixed Bottom Offshore Wind" + offwind_floating: "Floating Offshore Wind" + onwind: "Onshore Wind" + solar: "Solar" + EGS: "EGS" + coal-99CCS: "Coal-99CCS" + coal-95CCS: "Coal-95CCS" + CCGT-95CCS: "Gas-95CCS" + SMR: "SMR" + PHS: "Pumped Hydro Storage" + hydro: "Reservoir & Dam" + battery: "Battery Storage" + H2: "Hydrogen Storage" + lines: "Transmission Lines" + ror: "Run of River" + Load: "Load Shed" + res-elec: "Residential Electrical" + res-heat: "Residential Heating" + res-cool: "Residential Cooling" + com-elec: "Commercial Electrical" + com-heat: "Commercial Heating" + com-cool: "Commercial Cooling" + ind-elec: "Industrial Electrical" + ind-heat: "Industrial Heating" + trn-elec: "Transportation Electrical" \ No newline at end of file diff --git a/workflow/config/config.tutorial.yaml b/workflow/config/config.tutorial.yaml new file mode 100644 index 00000000..bbd8d56a --- /dev/null +++ b/workflow/config/config.tutorial.yaml @@ -0,0 +1,287 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Tutorial" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [texas] #"usa|texas|western|eastern" + clusters: [20] + opts: [REM-1000SEG] + ll: [v1.05] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: + - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: # Defines renewable weather year, and annual snapshot time-scope + start: "2019-01-01" + end: "2019-02-01" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 + co2limit: 180.3e+3 + co2limit_enable: true + co2base: 180.3e+6 + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired + StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] + Store: [] + Link: [] + + demand: #EFS used for given planning_horizons year (only ref/mod implemented) + EFS_case: reference # reference, medium, high + EFS_speed: moderate # slow, moderate, rapid + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true # Imposes ITLs over AC Lines + transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs + + +# docs : +links: + p_max_pu: 1.0 + p_nom_max: .inf + max_extension: 1000.0e+3 + +# docs : +load: + scaling_factor: 1.0 + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + ptc_modifier: + onwind: 18.2547 + geothermal: 18.2547 + biomass: 18.2547 + itc_modifier: + solar: 0.3 + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + ramp_limit_up: max + ramp_limit_down: max + # Mean heat-rates, VOM, and fuel are not used in the model, only for post processing purposes + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + # California: 0.5 + + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 4 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 8 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 8 + cplex-default: + threads: 4 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "12:00:00" diff --git a/workflow/config/config.validation.yaml b/workflow/config/config.validation.yaml new file mode 100644 index 00000000..44eed3dd --- /dev/null +++ b/workflow/config/config.validation.yaml @@ -0,0 +1,284 @@ +# PyPSA-USA Validation Configuration File + +run: + name: "Validation_REEDS" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: true # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [western] #"usa|texas|western|eastern" + clusters: [40] + opts: [Ep] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: + - 2019 #(2018-2023) + +foresight: 'perfect' + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2020-01-01" + inclusive: 'left' + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 # 0.8 * 1.841e+9 + co2limit_enable: false # For sector coupled studies + co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false # For sector coupled studies + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [] + StorageUnit: [] + Store: [] + Link: [] + + demand: + profile: eia # efs, eia + scale: 1 # efs, aeo, or a number + disaggregation: pop # pop + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + length_factor: 1.25 + interface_transmission_limits: true # Imposes ITLs over AC Lines + transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs + +# docs : +links: + p_max_pu: 0.7 + p_nom_max: .inf + +# docs : +load: + scaling_factor: 1.0 + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: False + aggregation_strategies: + generators: + committable: any + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: true + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 4 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 32 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 8 + cplex-default: + threads: 4 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "12:00:00" + + +# docs : +custom_files: + activate: false + files_path: '/Users/kamrantehranchi/Local_Documents/pypsa-usa/workflow/resources/CustomFiles/' + network_name: 'elec_s_40_ec.nc' \ No newline at end of file diff --git a/workflow/config/policy_constraints/.DS_Store b/workflow/config/policy_constraints/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Wed, 14 Aug 2024 08:45:04 -0700 Subject: [PATCH 02/17] sync to upstream --- workflow/rules/build_electricity.smk | 3 +- workflow/run_slurm.sh | 1 + workflow/scripts/add_electricity.py | 93 +++++++++++++++++- workflow/scripts/add_extra_components.py | 114 +++++++++++++++++++++-- workflow/scripts/constants.py | 4 + workflow/scripts/solve_network.py | 2 +- 6 files changed, 205 insertions(+), 12 deletions(-) diff --git a/workflow/rules/build_electricity.smk b/workflow/rules/build_electricity.smk index b69b46d4..83d21c9a 100644 --- a/workflow/rules/build_electricity.smk +++ b/workflow/rules/build_electricity.smk @@ -196,7 +196,7 @@ rule build_renewable_profiles: resources: mem_mb=ATLITE_NPROCESSES * 5000, wildcard_constraints: - technology="(?!hydro).*", # Any technology other than hydro + technology="(?!hydro|EGS).*", # Any technology other than hydro script: "../scripts/build_renewable_profiles.py" @@ -462,6 +462,7 @@ rule add_electricity: hydro_breakthrough=DATA + "breakthrough_network/base_grid/hydro.csv", bus2sub=RESOURCES + "{interconnect}/bus2sub.csv", pudl_fuel_costs=RESOURCES + "{interconnect}/pudl_fuel_costs.csv", + #specs_EGS=RESOURCES + "{interconnect}/specs_EGS.nc", output: RESOURCES + "{interconnect}/elec_base_network_l_pp.nc", log: diff --git a/workflow/run_slurm.sh b/workflow/run_slurm.sh index 21fb2f05..10f7cf3d 100644 --- a/workflow/run_slurm.sh +++ b/workflow/run_slurm.sh @@ -1,2 +1,3 @@ # SLURM specifications made in default.cluster.yaml & the individual rules +GRB_LICENSE_FILE=/share/software/user/restricted/gurobi/11.0.2/licenses/gurobi.lic snakemake --cluster "sbatch -A {cluster.account} --mail-type ALL --mail-user {cluster.email} -p {cluster.partition} -t {cluster.walltime} -o {cluster.output} -e {cluster.error} -c {threads} --mem {resources.mem_mb}" --cluster-config config/config.cluster.yaml --jobs 20 --latency-wait 60 --configfile config/config.validation_2023.yaml --rerun-incomplete diff --git a/workflow/scripts/add_electricity.py b/workflow/scripts/add_electricity.py index a3c2279c..068bca52 100755 --- a/workflow/scripts/add_electricity.py +++ b/workflow/scripts/add_electricity.py @@ -694,7 +694,7 @@ def attach_wind_and_solar( """ add_missing_carriers(n, carriers) for car in carriers: - if car == "hydro": + if any([c in car for c in ["hydro", "EGS"]]): continue with xr.open_dataset(getattr(input_profiles, "profile_" + car)) as ds: @@ -809,6 +809,88 @@ def attach_wind_and_solar( p_max_pu=bus_profiles, ) +def attach_egs( + n: pypsa.Network, + costs: pd.DataFrame, + input_profiles: str, + carriers: list[str], + extendable_carriers: dict[str, list[str]], + line_length_factor=1, +): + """ + Attached STM Calculated wind and solar capacity factor profiles to the + network. + """ + car = "EGS" + if car not in carriers: + return + + add_missing_carriers(n, carriers) + + lifetime = 25 # Following EGS supply curves by Aljubran et al. (2024) + discount_rate = load_costs(snakemake.input.tech_costs, snakemake.params.costs, snakemake.params.max_hours).loc[car, "discount rate"] + + with xr.open_dataset(getattr(input_profiles, "specs_EGS")) as ds_specs, xr.open_dataset(getattr(input_profiles, "profile_EGS")) as ds_profile: + + bus2sub = ( + pd.read_csv(input_profiles.bus2sub, dtype=str) + .drop("interconnect", axis=1) + .rename(columns={"Bus": "bus_id"}) + ) + + # IGNORE: Remove dropna(). Rather, apply dropna when creating the original dataset + df_specs = pd.merge(ds_specs.to_dataframe().reset_index().dropna(), bus2sub, on="sub_id", how="left") + df_specs["bus_id"] = df_specs["bus_id"].astype(str) + + # bus_id must be in index for pypsa to read it + df_specs.set_index("bus_id", inplace=True) + + # columns must be renamed to refer to the right quantities for pypsa to read it correctly + df_specs = df_specs.rename(columns={ + "capex_usd_kw": "capital_cost", + #"advanced_capex_usd_kw": "capital_cost", + "avail_capacity_mw": "p_nom_max", + "fixed_om": "fixed_om"}) + + # TODO: come up with proper values for these params + + df_specs["capital_cost"] = 1000 * (df_specs["capital_cost"] * calculate_annuity(lifetime, discount_rate) + df_specs["fixed_om"])#convert and annualize USD/kW to USD/MW-year + df_specs["efficiency"] = 1.0 + + # TODO: review what qualities need to be included. Currently limited for speedup. + qualities = [1]#df_specs.Quality.unique() + + for q in qualities: + suffix = " " + car# + f" Q{q}" + df_q = df_specs[df_specs["Quality"] == q] + + bus_list = df_q.index.values + capital_cost = df_q["capital_cost"] + p_nom_max_bus = df_q["p_nom_max"] + efficiency = df_q["efficiency"] # for now. + + # IGNORE: Remove dropna(). Rather, apply dropna when creating the original dataset + df_q_profile = pd.merge(ds_profile.sel(Quality=q).to_dataframe().dropna().reset_index(), + bus2sub, + on="sub_id", how="left") + bus_profiles = pd.pivot_table(df_q_profile, columns="bus_id", + index=["year", "Date"], values="capacity_factor") + + logger.info(f"Adding EGS (Resource Quality-{q}) capacity-factor profiles to the network.") + + n.madd( + "Generator", + bus_list, + suffix, + bus=bus_list, + carrier=car, + p_nom_extendable=car in extendable_carriers["Generator"], + p_nom_max=p_nom_max_bus, + # weight=weight_bus, + capital_cost=capital_cost, + efficiency=efficiency, + p_max_pu=bus_profiles, + ) def attach_battery_storage( n: pypsa.Network, @@ -1119,6 +1201,15 @@ def main(snakemake): plants = match_plant_to_bus(n, plants) + attach_egs( + n, + costs, + snakemake.input, + renewable_carriers, + extendable_carriers, + params.length_factor, + ) + attach_conventional_generators( n, costs, diff --git a/workflow/scripts/add_extra_components.py b/workflow/scripts/add_extra_components.py index a397e095..885caabe 100644 --- a/workflow/scripts/add_extra_components.py +++ b/workflow/scripts/add_extra_components.py @@ -476,6 +476,79 @@ def attach_multihorizon_generators( ) n.generators_t["p_max_pu"] = n.generators_t["p_max_pu"].join(p_max_pu_t) +def attach_multihorizon_egs( + n: pypsa.Network, + costs: pd.DataFrame, + costs_dict: dict, + gens: pd.DataFrame, + investment_year: int, +): + """ + Adds multiple investment options for EGS. + Arguments: + n: pypsa.Network, + costs: pd.DataFrame, + dataframe with costs of investment year + costs_dict: dict, + Dict of costs for each investment period + carriers: List[str] + List of carriers to add multiple investment options for + """ + if gens.empty or len(n.investment_periods) == 1: + return + + lifetime = 25 # Following EGS supply curves by Aljubran et al. (2024) + base_year = n.investment_periods[0] + base_capex = costs_dict[base_year].loc["EGS", "investment"] + learning_ratio = costs.loc["EGS", "investment"]/costs_dict[base_year].loc["EGS", "investment"] + capital_cost = learning_ratio * gens["capital_cost"] + + n.madd( + "Generator", + gens.index, + suffix=f" {investment_year}", + carrier=gens.carrier, + bus=gens.bus, + p_nom_min=0, + p_nom=0, + p_nom_max=gens.p_nom_max, + p_nom_extendable=True, + ramp_limit_up=gens.ramp_limit_up, + ramp_limit_down=gens.ramp_limit_down, + efficiency=gens.efficiency, + marginal_cost=gens.marginal_cost, + p_min_pu=gens.p_min_pu, + p_max_pu=gens.p_max_pu, + capital_cost=capital_cost, + build_year=investment_year, + lifetime=lifetime, + ) + + # time dependent factors added after + marginal_cost_t = n.generators_t["marginal_cost"][ + [x for x in gens.index if x in n.generators_t.marginal_cost.columns] + ] + marginal_cost_t = marginal_cost_t.rename( + columns={x: f"{x} {investment_year}" for x in marginal_cost_t.columns}, + ) + n.generators_t["marginal_cost"] = n.generators_t["marginal_cost"].join( + marginal_cost_t, + ) + + p_max_pu_t = n.generators_t["p_max_pu"][ + [x for x in gens.index if x in n.generators_t["p_max_pu"].columns] + ] + + p_max_pu_t = p_max_pu_t.rename( + columns={x: f"{x} {investment_year}" for x in p_max_pu_t.columns}, + ) + + n.generators_t["p_max_pu"] = n.generators_t["p_max_pu"].join(p_max_pu_t) + + # shift over time to capture decline + investment_year_idx = np.where(n.investment_periods == investment_year)[0][0] + cars = list(n.generators_t["p_max_pu"].filter(like="EGS").filter(like=str(investment_year)).columns) + n.generators_t["p_max_pu"].loc[n.investment_periods[investment_year_idx:], cars] = n.generators_t["p_max_pu"].loc[n.investment_periods[:len(n.investment_periods)-investment_year_idx], cars].values def attach_newCarrier_generators(n, costs, carriers, investment_year): """ @@ -515,30 +588,35 @@ def attach_newCarrier_generators(n, costs, carriers, investment_year): lifetime=costs.at[carrier, "lifetime"], ) - -def apply_itc(n, itc_modifier): +def apply_itc(n, itc_modifier, all_itc_eligible_carriers): """ Applies investment tax credit to all extendable components in the network. - Arguments: n: pypsa.Network, itc_modifier: dict, Dict of ITC modifiers for each carrier """ + if "all" in itc_modifier.keys(): + val = itc_modifier["all"] + itc_modifier = {car:val for car in all_itc_eligible_carriers} + for carrier in itc_modifier.keys(): carrier_mask = n.generators["carrier"] == carrier - n.generators.loc[carrier_mask, "capital_cost"] *= 1 - itc_modifier[carrier] + n.generators.loc[carrier_mask, "capital_cost"] *= (1 - itc_modifier[carrier]) - -def apply_ptc(n, ptc_modifier): +def apply_ptc(n, ptc_modifier, all_ptc_eligible_carriers): """ Applies production tax credit to all extendable components in the network. - Arguments: n: pypsa.Network, ptc_modifier: dict, Dict of PTC modifiers for each carrier """ + + if "all" in ptc_modifier.keys(): + val = ptc_modifier["all"] + ptc_modifier = {car:val for car in all_ptc_eligible_carriers} + for carrier in ptc_modifier.keys(): carrier_mask = n.generators["carrier"] == carrier mc = n.get_switchable_as_dense("Generator", "marginal_cost").loc[ @@ -598,12 +676,17 @@ def apply_ptc(n, ptc_modifier): if any("PHS" in s for s in elec_config["extendable_carriers"]["StorageUnit"]): attach_phs_storageunits(n, elec_config) + gens = gens[gens["carrier"].isin([car for car in elec_config["extendable_carriers"]["Generator"] if "EGS" not in car])] + egs_gens = n.generators[n.generators["p_nom_extendable"] == True] + egs_gens = egs_gens.loc[egs_gens["carrier"].str.contains("EGS")] + for investment_year in n.investment_periods: costs = costs_dict[investment_year] attach_storageunits(n, costs, elec_config, investment_year) attach_stores(n, costs, elec_config, investment_year) attach_hydrogen_pipelines(n, costs, elec_config, investment_year) attach_multihorizon_generators(n, costs, gens, investment_year) + attach_multihorizon_egs(n, costs, costs_dict, egs_gens, investment_year) attach_newCarrier_generators(n, costs, new_carriers, investment_year) if not gens.empty and not len(n.investment_periods) == 1: @@ -612,8 +695,21 @@ def apply_ptc(n, ptc_modifier): gens.index, ) # Remove duplicate generators from first investment period - apply_itc(n, snakemake.config["costs"]["itc_modifier"]) - apply_ptc(n, snakemake.config["costs"]["ptc_modifier"]) + all_itc_eligible_carriers = ( + set( + elec_config["renewable_carriers"] + + elec_config["extendable_carriers"]["StorageUnit"] + ) + ) + + all_ptc_eligible_carriers = ( + set( + elec_config["renewable_carriers"] + ) + ) + apply_itc(n, snakemake.config["costs"]["itc_modifier"], all_itc_eligible_carriers) + apply_ptc(n, snakemake.config["costs"]["ptc_modifier"], all_ptc_eligible_carriers) + add_nice_carrier_names(n, snakemake.config) n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards))) diff --git a/workflow/scripts/constants.py b/workflow/scripts/constants.py index e92f42e9..1b38fcca 100644 --- a/workflow/scripts/constants.py +++ b/workflow/scripts/constants.py @@ -743,6 +743,10 @@ "display_name": "Utility-Scale Battery Storage - 10Hr", "crp": 20, }, + "EGS": { + "display_name": "Geothermal - Hydro / Flash", + "crp": 30, + }, "8hr_PHS": { "display_name": "Pumped Storage Hydropower - National Class 1", "crp": 100, diff --git a/workflow/scripts/solve_network.py b/workflow/scripts/solve_network.py index e6a21497..e8ba3a4b 100644 --- a/workflow/scripts/solve_network.py +++ b/workflow/scripts/solve_network.py @@ -521,7 +521,7 @@ def add_interface_limits(n, sns, config): dims="Line", ) - n.model["Line-s"].loc[:, interface_lines_b0.index].sum(dims="Line") else: - line_flows = 0.0 + continue lhs = line_flows if ( From 80d0bd608ea06b942f304fdbd85bda8702eac3e9 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:21:33 -0700 Subject: [PATCH 03/17] memory --- workflow/rules/build_electricity.smk | 6 +++--- workflow/rules/build_sector.smk | 4 ++-- workflow/rules/retrieve.smk | 6 +++--- workflow/rules/solve_myopic.smk | 2 +- workflow/snakemake_profiles/slurm/config.yaml | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/workflow/rules/build_electricity.smk b/workflow/rules/build_electricity.smk index 83d21c9a..5276b0db 100644 --- a/workflow/rules/build_electricity.smk +++ b/workflow/rules/build_electricity.smk @@ -57,7 +57,7 @@ rule build_base_network: "logs/create_network/{interconnect}.log", threads: 1 resources: - mem_mb=1000, + mem_mb=5000, script: "../scripts/build_base_network.py" @@ -82,7 +82,7 @@ rule build_bus_regions: "logs/build_bus_regions/{interconnect}.log", threads: 1 resources: - mem_mb=1000, + mem_mb=5000, script: "../scripts/build_bus_regions.py" @@ -97,7 +97,7 @@ rule build_cost_data: LOGS + "costs_{year}.log", threads: 1 resources: - mem_mb=1000, + mem_mb=5000, script: "../scripts/build_cost_data.py" diff --git a/workflow/rules/build_sector.smk b/workflow/rules/build_sector.smk index 8ac4dcfc..5ee27aa6 100644 --- a/workflow/rules/build_sector.smk +++ b/workflow/rules/build_sector.smk @@ -174,7 +174,7 @@ rule build_simplified_population_layouts: # clustered_pop_layout=RESOURCES + "pop_layout_elec_s{simpl}.csv", clustered_pop_layout=RESOURCES + "{interconnect}/pop_layout_elec_s.csv", resources: - mem_mb=10000, + mem_mb=50000, log: # LOGS + "build_simplified_population_layouts_{simpl}", LOGS + "{interconnect}/build_simplified_population_layouts", @@ -208,7 +208,7 @@ rule build_clustered_population_layouts: # LOGS + "build_clustered_population_layouts_{simpl}_{clusters}.log", LOGS + "{interconnect}/build_clustered_population_layouts_{clusters}.log", resources: - mem_mb=10000, + mem_mb=50000, benchmark: # BENCHMARKS + "build_clustered_population_layouts/s{simpl}_{clusters}" BENCHMARKS + "{interconnect}/build_clustered_population_layouts/s_{clusters}" diff --git a/workflow/rules/retrieve.smk b/workflow/rules/retrieve.smk index 62e81b6f..bee3c52a 100644 --- a/workflow/rules/retrieve.smk +++ b/workflow/rules/retrieve.smk @@ -225,7 +225,7 @@ rule retrieve_cost_data_eur: log: LOGS + "retrieve_cost_data_eur_{year}.log", resources: - mem_mb=1000, + mem_mb=5000, script: "../scripts/retrieve_cost_data_eur.py" @@ -240,7 +240,7 @@ rule retrieve_cost_data_usa: log: LOGS + "retrieve_cost_data_usa.log", resources: - mem_mb=1000, + mem_mb=5000, script: "../scripts/retrieve_cost_data_usa.py" @@ -270,6 +270,6 @@ rule retrieve_pudl: log: LOGS + "retrieve_pudl.log", resources: - mem_mb=1000, + mem_mb=5000, script: "../scripts/retrieve_pudl.py" diff --git a/workflow/rules/solve_myopic.smk b/workflow/rules/solve_myopic.smk index ab6322b2..b314bfad 100644 --- a/workflow/rules/solve_myopic.smk +++ b/workflow/rules/solve_myopic.smk @@ -42,7 +42,7 @@ rule add_brownfield: + "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc", threads: 4 resources: - mem_mb=10000, + mem_mb=50000, log: LOGS + "add_brownfield_elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.log", diff --git a/workflow/snakemake_profiles/slurm/config.yaml b/workflow/snakemake_profiles/slurm/config.yaml index 271c8b4b..d3146598 100644 --- a/workflow/snakemake_profiles/slurm/config.yaml +++ b/workflow/snakemake_profiles/slurm/config.yaml @@ -1,6 +1,6 @@ cluster: sbatch --partition=serc --cpus-per-task={threads} --mem={resources.mem_mb} --job-name=smk-{rule}-{wildcards} --output=logs/{rule}/{rule}-{wildcards}-%j.out --error=logs/{rule}/{rule}-{wildcards}-.%j.err --mail-type ALL --mail-user ktehranchi@stanford.edu --account=iazevedo --ntasks=1 --nodes=1 --time={resources.walltime} default-resources: -- mem_mb=1000 +- mem_mb=5000 - walltime=00:30:00 restart-times: 1 max-jobs-per-second: 10 From 6a0d256f4a5819148ccd8eded721cca51b27b43a Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:15:53 -0700 Subject: [PATCH 04/17] increase memory --- workflow/rules/build_electricity.smk | 2 +- workflow/rules/retrieve.smk | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/workflow/rules/build_electricity.smk b/workflow/rules/build_electricity.smk index 5276b0db..5c9ecb9a 100644 --- a/workflow/rules/build_electricity.smk +++ b/workflow/rules/build_electricity.smk @@ -122,7 +122,7 @@ if config["enable"].get("build_cutout", False): "benchmarks/" + CDIR + "build_cutout_{interconnect}_{cutout}" threads: ATLITE_NPROCESSES resources: - mem_mb=ATLITE_NPROCESSES * 1000, + mem_mb=ATLITE_NPROCESSES * 5000, script: "../scripts/build_cutout.py" diff --git a/workflow/rules/retrieve.smk b/workflow/rules/retrieve.smk index bee3c52a..be533289 100644 --- a/workflow/rules/retrieve.smk +++ b/workflow/rules/retrieve.smk @@ -47,6 +47,8 @@ rule retrieve_zenodo_databundles: expand(DATA + "{file}", file=pypsa_usa_datafiles), log: "logs/retrieve/retrieve_databundles.log", + resources: + mem_mb=5000, conda: "../envs/environment.yaml" script: From 8642552e41c0630d6d4d850deba60e68d0f46dc5 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:31:07 -0700 Subject: [PATCH 05/17] fix config --- workflow/config/config.mod_default.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml index b9267325..359ffcf1 100644 --- a/workflow/config/config.mod_default.yaml +++ b/workflow/config/config.mod_default.yaml @@ -10,7 +10,7 @@ run: # docs : scenario: interconnect: [texas] #"usa|texas|western|eastern" - clusters: [8] + clusters: [7] opts: [REM-2000SEG] ll: [v1.0] scope: "total" # "urban", "rural", or "total" @@ -62,7 +62,7 @@ electricity: extendable_carriers: Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR] #offwind, offwind_floating, maybe include CCGT-CCS - StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage] # [Xhr-battery-storage (2-10 hours)] + StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] Store: [] Link: [] From 5f0af8e508f5745c733516f987e02721531b0106 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:01:14 -0700 Subject: [PATCH 06/17] add pickling capability --- workflow/config/config.egs.yaml | 1 + workflow/config/config.mod_default.yaml | 1 + workflow/rules/build_electricity.smk | 4 ++-- workflow/scripts/add_electricity.py | 4 +++- workflow/scripts/simplify_network.py | 4 +++- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml index 0a510673..63a5d0a1 100644 --- a/workflow/config/config.egs.yaml +++ b/workflow/config/config.egs.yaml @@ -11,6 +11,7 @@ run: scenario: interconnect: [western] #"usa|texas|western|eastern" clusters: [33] + simpl: [200] opts: [REM-2000SEG] ll: [v1.0] scope: "total" # "urban", "rural", or "total" diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml index 359ffcf1..5904a6d0 100644 --- a/workflow/config/config.mod_default.yaml +++ b/workflow/config/config.mod_default.yaml @@ -11,6 +11,7 @@ run: scenario: interconnect: [texas] #"usa|texas|western|eastern" clusters: [7] + simpl: [200] opts: [REM-2000SEG] ll: [v1.0] scope: "total" # "urban", "rural", or "total" diff --git a/workflow/rules/build_electricity.smk b/workflow/rules/build_electricity.smk index b01bb991..1f089d9b 100644 --- a/workflow/rules/build_electricity.smk +++ b/workflow/rules/build_electricity.smk @@ -464,7 +464,7 @@ rule add_electricity: pudl_fuel_costs=RESOURCES + "{interconnect}/pudl_fuel_costs.csv", #specs_EGS=RESOURCES + "{interconnect}/specs_EGS.nc", output: - RESOURCES + "{interconnect}/elec_base_network_l_pp.nc", + RESOURCES + "{interconnect}/elec_base_network_l_pp.pkl", log: LOGS + "{interconnect}/add_electricity.log", benchmark: @@ -486,7 +486,7 @@ rule simplify_network: input: bus2sub=RESOURCES + "{interconnect}/bus2sub.csv", sub=RESOURCES + "{interconnect}/sub.csv", - network=RESOURCES + "{interconnect}/elec_base_network_l_pp.nc", + network=RESOURCES + "{interconnect}/elec_base_network_l_pp.pkl", regions_onshore=RESOURCES + "{interconnect}/regions_onshore.geojson", regions_offshore=RESOURCES + "{interconnect}/regions_offshore.geojson", output: diff --git a/workflow/scripts/add_electricity.py b/workflow/scripts/add_electricity.py index 068bca52..4daf0fd1 100755 --- a/workflow/scripts/add_electricity.py +++ b/workflow/scripts/add_electricity.py @@ -60,6 +60,7 @@ from shapely.geometry import Point from shapely.prepared import prep from sklearn.neighbors import BallTree +import dill as pickle idx = pd.IndexSlice @@ -1350,7 +1351,8 @@ def main(snakemake): n.generators_t.p_max_pu = reduce_float_memory(n.generators_t.p_max_pu) n.generators_t.marginal_cost = reduce_float_memory(n.generators_t.marginal_cost) - n.export_to_netcdf(snakemake.output[0]) + pickle.dump(n, open(snakemake.output[0], "wb")) + # n.export_to_netcdf(snakemake.output[0]) logger.info(test_network_datatype_consistency(n)) diff --git a/workflow/scripts/simplify_network.py b/workflow/scripts/simplify_network.py index 155c5361..76871c58 100644 --- a/workflow/scripts/simplify_network.py +++ b/workflow/scripts/simplify_network.py @@ -20,6 +20,7 @@ ) from cluster_network import cluster_regions, clustering_for_n_clusters from pypsa.clustering.spatial import get_clustering_from_busmap +import dill as pickle logger = logging.getLogger(__name__) @@ -230,7 +231,8 @@ def assign_line_lengths(n, line_length_factor): "aggregation_zones" ] - n = pypsa.Network(snakemake.input.network) + # n = pypsa.Network(snakemake.input.network) + n = pickle.load(open(snakemake.input.network, "rb")) n.generators.drop( columns=["ba_eia", "ba_ads"], From 3076f93aa75b18d7da30d5ef505850d0d65263e4 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:39:44 -0700 Subject: [PATCH 07/17] update ITC/PTC modules and config based on 2024 NREL ATB inputs --- workflow/Snakefile | 1 - workflow/config/config.common.yaml | 21 ++++++++++++++-- workflow/config/config.egs.yaml | 4 +-- workflow/envs/environment.yaml | 1 + workflow/scripts/add_extra_components.py | 32 +++++++----------------- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/workflow/Snakefile b/workflow/Snakefile index 88d47867..2b5aa749 100644 --- a/workflow/Snakefile +++ b/workflow/Snakefile @@ -92,7 +92,6 @@ wildcard_constraints: # Merge subworkflow configs and main config -configfile: "config/config.tutorial.yaml" configfile: "config/config.cluster.yaml" configfile: "config/config.common.yaml" configfile: "config/config.plotting.yaml" diff --git a/workflow/config/config.common.yaml b/workflow/config/config.common.yaml index a39e8e9a..d8776f59 100644 --- a/workflow/config/config.common.yaml +++ b/workflow/config/config.common.yaml @@ -134,5 +134,22 @@ offshore_network: bus_spacing: 25000 # km costs: - itc_modifier: {} - ptc_modifier: {} \ No newline at end of file + itc_modifier: + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + geothermal: 0.3 + SMR: 0.3 + nuclear: 0.3 + hydro: 0.3 + 4hr_battery_storage: 0.3 + 6hr_battery_storage: 0.3 + 8hr_battery_storage: 0.3 + 10hr_battery_storage: 0.3 + 8hr_PHS: 0.3 + 10hr_PHS: 0.3 + 12hr_PHS: 0.3 + ptc_modifier: + solar: 27.5 + onwind: 27.5 + biomass: 27.5 \ No newline at end of file diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml index 63a5d0a1..2d457a91 100644 --- a/workflow/config/config.egs.yaml +++ b/workflow/config/config.egs.yaml @@ -62,8 +62,8 @@ electricity: H2: 168 extendable_carriers: - Generator: [solar, onwind, offwind, offwind_floating, EGS, OCGT, CCGT, coal, CCGT-95CCS] #offwind, offwind_floating, maybe include CCGT-CCS - StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours)] + Generator: [solar, onwind, offwind, offwind_floating, EGS, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR] #offwind, offwind_floating, maybe include CCGT-CCS + StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] Store: [] Link: [] diff --git a/workflow/envs/environment.yaml b/workflow/envs/environment.yaml index a97cd5dc..db45a51e 100644 --- a/workflow/envs/environment.yaml +++ b/workflow/envs/environment.yaml @@ -63,3 +63,4 @@ dependencies: - tsam>=1.1.0 - gurobipy==10.0.3 - highspy + - dill diff --git a/workflow/scripts/add_extra_components.py b/workflow/scripts/add_extra_components.py index 885caabe..0fbf3970 100644 --- a/workflow/scripts/add_extra_components.py +++ b/workflow/scripts/add_extra_components.py @@ -588,7 +588,7 @@ def attach_newCarrier_generators(n, costs, carriers, investment_year): lifetime=costs.at[carrier, "lifetime"], ) -def apply_itc(n, itc_modifier, all_itc_eligible_carriers): +def apply_itc(n, itc_modifier): """ Applies investment tax credit to all extendable components in the network. Arguments: @@ -596,15 +596,17 @@ def apply_itc(n, itc_modifier, all_itc_eligible_carriers): itc_modifier: dict, Dict of ITC modifiers for each carrier """ - if "all" in itc_modifier.keys(): - val = itc_modifier["all"] - itc_modifier = {car:val for car in all_itc_eligible_carriers} for carrier in itc_modifier.keys(): + # apply to generators carrier_mask = n.generators["carrier"] == carrier n.generators.loc[carrier_mask, "capital_cost"] *= (1 - itc_modifier[carrier]) -def apply_ptc(n, ptc_modifier, all_ptc_eligible_carriers): + # apply to storage units + carrier_mask = n.storage_units["carrier"] == carrier + n.storage_units.loc[carrier_mask, "capital_cost"] *= (1 - itc_modifier[carrier]) + +def apply_ptc(n, ptc_modifier): """ Applies production tax credit to all extendable components in the network. Arguments: @@ -613,10 +615,6 @@ def apply_ptc(n, ptc_modifier, all_ptc_eligible_carriers): Dict of PTC modifiers for each carrier """ - if "all" in ptc_modifier.keys(): - val = ptc_modifier["all"] - ptc_modifier = {car:val for car in all_ptc_eligible_carriers} - for carrier in ptc_modifier.keys(): carrier_mask = n.generators["carrier"] == carrier mc = n.get_switchable_as_dense("Generator", "marginal_cost").loc[ @@ -695,20 +693,8 @@ def apply_ptc(n, ptc_modifier, all_ptc_eligible_carriers): gens.index, ) # Remove duplicate generators from first investment period - all_itc_eligible_carriers = ( - set( - elec_config["renewable_carriers"] + - elec_config["extendable_carriers"]["StorageUnit"] - ) - ) - - all_ptc_eligible_carriers = ( - set( - elec_config["renewable_carriers"] - ) - ) - apply_itc(n, snakemake.config["costs"]["itc_modifier"], all_itc_eligible_carriers) - apply_ptc(n, snakemake.config["costs"]["ptc_modifier"], all_ptc_eligible_carriers) + apply_itc(n, snakemake.config["costs"]["itc_modifier"]) + apply_ptc(n, snakemake.config["costs"]["ptc_modifier"]) add_nice_carrier_names(n, snakemake.config) From 32902cd2cafe6ff6607b43fd5c5bceb6ad5b5495 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Sun, 18 Aug 2024 09:37:27 -0700 Subject: [PATCH 08/17] small fix --- workflow/config/config.cluster.yaml | 14 +++++----- workflow/config/config.common.yaml | 34 ++++++++++++------------- workflow/config/config.egs.yaml | 3 +++ workflow/config/config.mod_default.yaml | 5 +++- workflow/rules/common.smk | 12 ++++----- workflow/rules/solve_electricity.smk | 3 ++- workflow/run_slurm.sh | 2 +- workflow/scripts/cluster_network.py | 3 ++- 8 files changed, 42 insertions(+), 34 deletions(-) diff --git a/workflow/config/config.cluster.yaml b/workflow/config/config.cluster.yaml index 5c44ff24..a37b1841 100644 --- a/workflow/config/config.cluster.yaml +++ b/workflow/config/config.cluster.yaml @@ -2,7 +2,7 @@ __default__: account: horne partition: serc email: m.j.aljubran@gmail.com - walltime: 00:30:00 # time limit for each job + walltime: "04:00:00" # time limit for each job cpus_per_task: 1 # number of cores per job chdir: $GROUP_SCRATCH/aljubrmj/framework_4/hl_markets/pypsa-usa/workflow/ output: logs/{rule}/log-%j.out @@ -11,19 +11,19 @@ __default__: build_renewable_profiles: - walltime: 02:00:00 + walltime: "04:00:00" add_electricity: - walltime: 02:00:00 + walltime: "04:00:00" simplify_network: - walltime: 02:00:00 + walltime: "04:00:00" cluster_network: - walltime: 02:00:00 + walltime: "04:00:00" solve_network: - walltime: 06:00:00 + walltime: "24:00:00" solve_network_validation: - walltime: 06:00:00 + walltime: "24:00:00" diff --git a/workflow/config/config.common.yaml b/workflow/config/config.common.yaml index d8776f59..3a665958 100644 --- a/workflow/config/config.common.yaml +++ b/workflow/config/config.common.yaml @@ -135,21 +135,21 @@ offshore_network: costs: itc_modifier: - offwind: 0.3 - offwind_floating: 0.3 - EGS: 0.3 - geothermal: 0.3 - SMR: 0.3 - nuclear: 0.3 - hydro: 0.3 - 4hr_battery_storage: 0.3 - 6hr_battery_storage: 0.3 - 8hr_battery_storage: 0.3 - 10hr_battery_storage: 0.3 - 8hr_PHS: 0.3 - 10hr_PHS: 0.3 - 12hr_PHS: 0.3 + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + geothermal: 0.3 + SMR: 0.3 + nuclear: 0.3 + hydro: 0.3 + 4hr_battery_storage: 0.3 + 6hr_battery_storage: 0.3 + 8hr_battery_storage: 0.3 + 10hr_battery_storage: 0.3 + 8hr_PHS: 0.3 + 10hr_PHS: 0.3 + 12hr_PHS: 0.3 ptc_modifier: - solar: 27.5 - onwind: 27.5 - biomass: 27.5 \ No newline at end of file + solar: 27.5 + onwind: 27.5 + biomass: 27.5 \ No newline at end of file diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml index 2d457a91..58f4d6a5 100644 --- a/workflow/config/config.egs.yaml +++ b/workflow/config/config.egs.yaml @@ -181,6 +181,8 @@ clustering: aggregation_strategies: generators: committable: any + build_year: 'capacity_weighted_average' + lifetime: 'capacity_weighted_average' start_up_cost: 'capacity_weighted_average' min_up_time: 'capacity_weighted_average' min_down_time: 'capacity_weighted_average' @@ -276,6 +278,7 @@ solving: mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 walltime: "24:00:00" + cores: 24 # docs : diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml index 5904a6d0..882b4414 100644 --- a/workflow/config/config.mod_default.yaml +++ b/workflow/config/config.mod_default.yaml @@ -181,6 +181,8 @@ clustering: aggregation_strategies: generators: committable: any + build_year: 'capacity_weighted_average' + lifetime: 'capacity_weighted_average' start_up_cost: 'capacity_weighted_average' min_up_time: 'capacity_weighted_average' min_down_time: 'capacity_weighted_average' @@ -253,7 +255,7 @@ solving: FeasibilityTol: 1.e-4 OptimalityTol: 1.e-4 ObjScale: -0.5 - threads: 8 + threads: 24 Seed: 123 gurobi-fallback: # Use gurobi defaults name: gurobi @@ -276,6 +278,7 @@ solving: mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 walltime: "24:00:00" + cores: 24 # docs : diff --git a/workflow/rules/common.smk b/workflow/rules/common.smk index ef1fdf43..5599e2bb 100644 --- a/workflow/rules/common.smk +++ b/workflow/rules/common.smk @@ -121,11 +121,11 @@ def interconnect_mem(w): def interconnect_mem_a(w): mem = 15000 * len(config_provider("scenario", "planning_horizons")(w)) if w.interconnect == "usa": - return int(mem * 2) + return int(mem * 4) elif w.interconnect == "eastern": - return int(mem * 1.5) + return int(mem * 3) elif w.interconnect == "western": - return int(mem) + return int(mem * 2) elif w.interconnect == "texas": return int(mem * 0.5) @@ -137,7 +137,7 @@ def interconnect_mem_s(w): elif w.interconnect == "eastern": return int(mem * 3) elif w.interconnect == "western": - return int(mem) + return int(mem * 2) elif w.interconnect == "texas": return int(mem * 0.5) @@ -149,7 +149,7 @@ def interconnect_mem_c(w): elif w.interconnect == "eastern": return int(mem * 3) elif w.interconnect == "western": - return int(mem) * 2 + return int(mem * 2) elif w.interconnect == "texas": return int(mem * 0.75) @@ -161,7 +161,7 @@ def interconnect_mem_prepare(w): elif w.interconnect == "eastern": return int(mem * 3) elif w.interconnect == "western": - return int(mem) * 2 + return int(mem * 2) elif w.interconnect == "texas": return int(mem * 0.75) diff --git a/workflow/rules/solve_electricity.smk b/workflow/rules/solve_electricity.smk index 9e68ca87..0657a9e2 100644 --- a/workflow/rules/solve_electricity.smk +++ b/workflow/rules/solve_electricity.smk @@ -34,9 +34,10 @@ rule solve_network: BENCHMARKS + "solve_network/{interconnect}/elec_s{simpl}_c{clusters}_ec_l{ll}_{opts}_{sector}" ) - threads: 8 + threads: 24 resources: mem_mb=memory, + cores=config["solving"].get("cores", 24), walltime=config["solving"].get("walltime", "12:00:00"), conda: "../envs/environment.yaml" diff --git a/workflow/run_slurm.sh b/workflow/run_slurm.sh index 10f7cf3d..de49c73b 100644 --- a/workflow/run_slurm.sh +++ b/workflow/run_slurm.sh @@ -1,3 +1,3 @@ # SLURM specifications made in default.cluster.yaml & the individual rules GRB_LICENSE_FILE=/share/software/user/restricted/gurobi/11.0.2/licenses/gurobi.lic -snakemake --cluster "sbatch -A {cluster.account} --mail-type ALL --mail-user {cluster.email} -p {cluster.partition} -t {cluster.walltime} -o {cluster.output} -e {cluster.error} -c {threads} --mem {resources.mem_mb}" --cluster-config config/config.cluster.yaml --jobs 20 --latency-wait 60 --configfile config/config.validation_2023.yaml --rerun-incomplete +snakemake --cluster "sbatch -A {cluster.account} --mail-type ALL --mail-user {cluster.email} -p {cluster.partition} -t {cluster.walltime} -o {cluster.output} -e {cluster.error} -c {threads} --mem {resources.mem_mb}" --cluster-config config/config.cluster.yaml --jobs 20 --latency-wait 120 --configfile config/config.validation_2023.yaml --rerun-incomplete diff --git a/workflow/scripts/cluster_network.py b/workflow/scripts/cluster_network.py index c538eb52..2f55121a 100644 --- a/workflow/scripts/cluster_network.py +++ b/workflow/scripts/cluster_network.py @@ -612,7 +612,8 @@ def plot_busmap_for_n_clusters(n, n_clusters, fn=None): if params.replace_lines_with_links: custom_busmap = n.buses.reeds_zone n.buses.interconnect = n.buses.nerc_reg.map(REEDS_NERC_INTERCONNECT_MAPPER) - + n.lines.drop(columns=["interconnect"], inplace=True) + clustering = clustering_for_n_clusters( n, n_clusters, From 05b096e39abaf18456cbb61f058e5d5789790537 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Sun, 18 Aug 2024 11:26:57 -0700 Subject: [PATCH 09/17] increase mem_a --- workflow/rules/common.smk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow/rules/common.smk b/workflow/rules/common.smk index 5599e2bb..fec1d904 100644 --- a/workflow/rules/common.smk +++ b/workflow/rules/common.smk @@ -119,7 +119,7 @@ def interconnect_mem(w): def interconnect_mem_a(w): - mem = 15000 * len(config_provider("scenario", "planning_horizons")(w)) + mem = 30000 * len(config_provider("scenario", "planning_horizons")(w)) if w.interconnect == "usa": return int(mem * 4) elif w.interconnect == "eastern": From 1c629627b47459066780e7673cd924a9e3b05dbb Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Sun, 18 Aug 2024 11:48:32 -0700 Subject: [PATCH 10/17] direct phs path in add_extra_components to repo_data --- workflow/rules/build_electricity.smk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow/rules/build_electricity.smk b/workflow/rules/build_electricity.smk index 1f089d9b..171ddb51 100644 --- a/workflow/rules/build_electricity.smk +++ b/workflow/rules/build_electricity.smk @@ -550,8 +550,8 @@ rule cluster_network: rule add_extra_components: input: **{ - f"phs_shp_{hour}": DATA - + f"psh/40-100-dam-height-{hour}hr-no-croplands-no-ephemeral-no-highways.gpkg" + f"phs_shp_{hour}": + f"repo_data/psh/40-100-dam-height-{hour}hr-no-croplands-no-ephemeral-no-highways.gpkg" for phs_tech in config["electricity"]["extendable_carriers"]["StorageUnit"] if "PHS" in phs_tech for hour in phs_tech.split("hr_") From 586ed377e6fe4e7447ca7924ad442883e64b93b3 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:43:12 -0700 Subject: [PATCH 11/17] increase cluster walltime for build_rules --- workflow/config/config.cluster.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/workflow/config/config.cluster.yaml b/workflow/config/config.cluster.yaml index a37b1841..47af4823 100644 --- a/workflow/config/config.cluster.yaml +++ b/workflow/config/config.cluster.yaml @@ -11,16 +11,16 @@ __default__: build_renewable_profiles: - walltime: "04:00:00" + walltime: "24:00:00" add_electricity: - walltime: "04:00:00" + walltime: "24:00:00" simplify_network: - walltime: "04:00:00" + walltime: "24:00:00" cluster_network: - walltime: "04:00:00" + walltime: "24:00:00" solve_network: walltime: "24:00:00" From 55347eeacc54c8c12c813fecb73b573c53740c34 Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:54:43 -0700 Subject: [PATCH 12/17] remove config --- workflow/config/config.api.yaml | 4 - workflow/config/config.cluster.yaml | 29 - workflow/config/config.common.yaml | 155 -- workflow/config/config.default.yaml | 295 ---- workflow/config/config.egs.yaml | 288 ---- workflow/config/config.mod_default.yaml | 288 ---- workflow/config/config.plotting.yaml | 122 -- workflow/config/config.tutorial.yaml | 287 ---- workflow/config/config.validation.yaml | 284 ---- workflow/config/policy_constraints/.DS_Store | Bin 6148 -> 0 bytes .../policy_constraints/SAFE_regional_prm.csv | 2 - .../policy_constraints/agg_p_nom_minmax.csv | 2 - .../portfolio_standards.csv | 2 - .../policy_constraints/reeds/ces_fraction.csv | 17 - .../reeds/offshore_req_30by30.csv | 15 - .../reeds/offshore_req_default.csv | 10 - .../policy_constraints/reeds/prm_annual.csv | 311 ---- .../policy_constraints/reeds/rggi_states.csv | 12 - .../policy_constraints/reeds/rggicon.csv | 41 - .../policy_constraints/reeds/rps_fraction.csv | 1307 ----------------- .../reeds/storage_mandates.csv | 276 ---- .../regional_Co2_limits.csv | 54 - .../transmission_interface_limits.csv | 4 - 23 files changed, 3805 deletions(-) delete mode 100644 workflow/config/config.api.yaml delete mode 100644 workflow/config/config.cluster.yaml delete mode 100644 workflow/config/config.common.yaml delete mode 100644 workflow/config/config.default.yaml delete mode 100644 workflow/config/config.egs.yaml delete mode 100644 workflow/config/config.mod_default.yaml delete mode 100644 workflow/config/config.plotting.yaml delete mode 100644 workflow/config/config.tutorial.yaml delete mode 100644 workflow/config/config.validation.yaml delete mode 100644 workflow/config/policy_constraints/.DS_Store delete mode 100644 workflow/config/policy_constraints/SAFE_regional_prm.csv delete mode 100644 workflow/config/policy_constraints/agg_p_nom_minmax.csv delete mode 100644 workflow/config/policy_constraints/portfolio_standards.csv delete mode 100644 workflow/config/policy_constraints/reeds/ces_fraction.csv delete mode 100644 workflow/config/policy_constraints/reeds/offshore_req_30by30.csv delete mode 100644 workflow/config/policy_constraints/reeds/offshore_req_default.csv delete mode 100644 workflow/config/policy_constraints/reeds/prm_annual.csv delete mode 100644 workflow/config/policy_constraints/reeds/rggi_states.csv delete mode 100644 workflow/config/policy_constraints/reeds/rggicon.csv delete mode 100644 workflow/config/policy_constraints/reeds/rps_fraction.csv delete mode 100644 workflow/config/policy_constraints/reeds/storage_mandates.csv delete mode 100644 workflow/config/policy_constraints/regional_Co2_limits.csv delete mode 100644 workflow/config/policy_constraints/transmission_interface_limits.csv diff --git a/workflow/config/config.api.yaml b/workflow/config/config.api.yaml deleted file mode 100644 index eb7afdee..00000000 --- a/workflow/config/config.api.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# holds user api keys - -api: - eia: kWdnW4WaIeeq2bsihF75w06C1FKiavVVg6he0CT7 diff --git a/workflow/config/config.cluster.yaml b/workflow/config/config.cluster.yaml deleted file mode 100644 index 47af4823..00000000 --- a/workflow/config/config.cluster.yaml +++ /dev/null @@ -1,29 +0,0 @@ -__default__: - account: horne - partition: serc - email: m.j.aljubran@gmail.com - walltime: "04:00:00" # time limit for each job - cpus_per_task: 1 # number of cores per job - chdir: $GROUP_SCRATCH/aljubrmj/framework_4/hl_markets/pypsa-usa/workflow/ - output: logs/{rule}/log-%j.out - error: logs/{rule}/errlog-%j.err - - - -build_renewable_profiles: - walltime: "24:00:00" - -add_electricity: - walltime: "24:00:00" - -simplify_network: - walltime: "24:00:00" - -cluster_network: - walltime: "24:00:00" - -solve_network: - walltime: "24:00:00" - -solve_network_validation: - walltime: "24:00:00" diff --git a/workflow/config/config.common.yaml b/workflow/config/config.common.yaml deleted file mode 100644 index 3a665958..00000000 --- a/workflow/config/config.common.yaml +++ /dev/null @@ -1,155 +0,0 @@ - -countries: [US] - -network_configuration: "pypsa-usa" # "pypsa-usa" or "ads2032" - - -# docs : -renewable: - onwind: - cutout: era5_2019 - resource: - method: wind - turbine: Vestas_V112_3MW - add_cutout_windspeed: true - capacity_per_sqkm: 3 # conservative, ScholzPhd Tab 4.3.1: 10MW/km^2 - correction_factor: 1 # 0.93 - corine: - #all keys labeled corrine are actually copernicus codes. Using the name corrine bc using the pypsa-eur convention: https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf - grid_codes: [20, 30, 40, 60, 100, 112, 113, 114, 115] - distance: 10 #buffer from distance_grid_codes that are to be excluded - distance_grid_codes: [50] - natura: true - cec: true - potential: conservative # simple or conservative - clip_p_max_pu: 1.e-2 - extendable: true - offwind: - cutout: era5_2019 - resource: - method: wind - turbine: NREL_ReferenceTurbine_2020ATB_5.5MW - # add_cutout_windspeed: true - capacity_per_sqkm: 3 # 2021–2022 Transmission Plan, CAISO - correction_factor: 1 # 0.8855 # proxy for wake losses, from 10.1016/j.energy.2018.08.153 - corine: - grid_codes: [80, 200] #page 28 of https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf - natura: true - boem_screen: true - max_depth: 60 # meters, ref https://www.nrel.gov/docs/fy16osti/66599.pdf - min_shore_distance: 22000 # meters - max_shore_distance: 65000 # meters - potential: conservative # simple or conservative - clip_p_max_pu: 1.e-2 - extendable: true - offwind_floating: - cutout: era5_2019 - resource: - method: wind - turbine: NREL_ReferenceTurbine_2020ATB_15MW_offshore - add_cutout_windspeed: true - capacity_per_sqkm: 3 # 2021–2022 Transmission Plan, CAISO - correction_factor: 1 # 0.8855 # proxy for wake losses, from 10.1016/j.energy.2018.08.153 - corine: - grid_codes: [80, 200] #page 28 of https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf - natura: true - boem_screen: true - min_depth: 60 # meters, ref https://www.nrel.gov/docs/fy16osti/66599.pdf - max_depth: 1300 # meters, ref https://www.nrel.gov/docs/fy22osti/83650.pdf - min_shore_distance: 22000 # meters - max_shore_distance: 65000 # meters - potential: conservative # simple or conservative - clip_p_max_pu: 1.e-2 - extendable: true - solar: - cutout: era5_2019 - resource: - method: pv - panel: CSi - orientation: latitude_optimal # will lead into optimal - capacity_per_sqkm: 4.6 # From 1.7 to 4.6 addresses issue #361 - TODO revisit this assumption - correction_factor: 1 # 0.854337 - corine: - grid_codes: [20, 30, 40, 60, 90, 100] #see above for codes - natura: true - cec: true - potential: conservative # simple or conservative - clip_p_max_pu: 1.e-2 - extendable: true - hydro: - cutout: era5_2019 - carriers: [ror, PHS, hydro] - PHS_max_hours: 6 - resource: - method: hydro - hydrobasins: resources/hybas_na_lev06_v1c.shp - flowspeed: 1.0 # m/s - hydro_max_hours: "energy_capacity_totals_by_country" # not active - clip_min_inflow: 1.0 - extendable: true - normalization: - method: hydro_capacities - year: 2013 - multiplier: 1.1 # multiplier applied after the normalization of the hydro production; default 1.0 - - -# docs : -atlite: - default_cutout: era5_2019 - nprocesses: 8 - show_progress: false # false saves time - cutouts: - era5_2019: - module: era5 # in priority order - time: ['2019', '2019'] - interconnects: - western: - x: [-126, -99] - y: [27, 50] - dx: 0.3 - dy: 0.3 - eastern: - x: [-109, -65] - y: [23, 50] - dx: 0.3 - dy: 0.3 - texas: - x: [-110, -90] - y: [24, 37] - dx: 0.3 - dy: 0.3 - usa: - x: [-126, -65] - y: [23, 50] - dx: 0.3 - dy: 0.3 - - -# docs : -offshore_shape: - use: eez #options are ca_osw, eez - -offshore_network: - enable: true # set to true to enable offshore network - bus_spacing: 25000 # km - -costs: - itc_modifier: - offwind: 0.3 - offwind_floating: 0.3 - EGS: 0.3 - geothermal: 0.3 - SMR: 0.3 - nuclear: 0.3 - hydro: 0.3 - 4hr_battery_storage: 0.3 - 6hr_battery_storage: 0.3 - 8hr_battery_storage: 0.3 - 10hr_battery_storage: 0.3 - 8hr_PHS: 0.3 - 10hr_PHS: 0.3 - 12hr_PHS: 0.3 - ptc_modifier: - solar: 27.5 - onwind: 27.5 - biomass: 27.5 \ No newline at end of file diff --git a/workflow/config/config.default.yaml b/workflow/config/config.default.yaml deleted file mode 100644 index 877e0dd6..00000000 --- a/workflow/config/config.default.yaml +++ /dev/null @@ -1,295 +0,0 @@ -# PyPSA-USA Default Configuration File - -run: - name: "Default" # use this to keep track of runs with different settings - disable_progressbar: false # set to true to disable the progressbar - shared_resources: false # set to true to share the default resources across runs - shared_cutouts: true # set to true to share the default cutout(s) across runs - validation: false # set to true to run back-casting plots - -# docs : -scenario: - interconnect: [western] #"usa|texas|western|eastern" - clusters: [40] - opts: [REM-1000SEG] - ll: [v1.0] - scope: "total" # "urban", "rural", or "total" - sector: "" # G - planning_horizons: - - 2030 #(2018-2023, 2030, 2040, 2050) - -foresight: 'perfect' - - -# docs : -enable: - build_cutout: false - -snapshots: - start: "2019-01-01" - end: "2020-01-01" - inclusive: "left" - - -# docs : -electricity: - conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network - renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network - voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" - co2limit: 1.4728e+9 - co2limit_enable: false - co2base: 226.86e+6 - gaslimit: false # global gas usage limit of X MWh_th - gaslimit_enable: false - retirement: economic # "economic" or "technical" - SAFE_reservemargin: 0.14 - regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' - agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' - portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' - SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' - transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' - - - operational_reserve: - activate: false - epsilon_load: 0.02 - epsilon_vres: 0.02 - contingency: 4000 - - max_hours: - battery: 6 - H2: 168 - - extendable_carriers: - Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired - StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] - Store: [] - Link: [] - - demand: - profile: eia # efs, eia - scenario: - efs_case: reference # reference, medium, high - efs_speed: moderate # slow, moderate, rapid - aeo: reference - - autarky: - enable: false - by_country: false - -# docs : -conventional: - unit_commitment: false - dynamic_fuel_price: - pudl: true - wholesale: true - - -# docs : -lines: - types: # All temporary values, need to be updated - 115.: "Al/St 240/40 2-bundle 220.0" - 138.: "Al/St 240/40 2-bundle 220.0" - 161.: "Al/St 240/40 2-bundle 220.0" - 230.: "Al/St 240/40 2-bundle 220.0" - 345.: "Al/St 240/40 4-bundle 380.0" - 500.: "Al/St 560/50 4-bundle 750.0" - 765.: "Al/St 560/50 4-bundle 750.0" - s_max_pu: 0.7 - s_nom_max: .inf - max_extension: 1000.0e+3 - length_factor: 1.25 - interface_transmission_limits: true # Imposes ITLs over AC Lines - transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs - - -# docs : -links: - p_max_pu: 1.0 - p_nom_max: .inf - max_extension: 1000.0e+3 - - -# docs : -costs: - social_discount_rate: 0.02 - version: v0.6.0 - rooftop_share: 0.0 - ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] - fill_values: - FOM: 0 - VOM: 0 - efficiency: 1 - fuel: 0 - investment: 0 - lifetime: 25 - "CO2 intensity": 0 - "discount rate": 0.07 - marginal_cost: - solar: 0.00 - onwind: 0.00 - offwind: 0.00 - hydro: 0. - H2: 0. - electrolysis: 0. - fuel cell: 0. - battery: 0. - battery inverter: 0. - emission_prices: # in currency per tonne emission, only used with the option Ep - enable: false - co2: 0. - co2_monthly_prices: false - ptc_modifier: - onwind: 18.2547 - geothermal: 18.2547 - biomass: 18.2547 - itc_modifier: - solar: 0.3 - offwind: 0.3 - offwind_floating: 0.3 - EGS: 0.3 - -# docs : -sector: - co2_sequestration_potential: 0 - natural_gas: - allow_imports_exports: true # false to be implemented - cyclic_storage: false - heating: - heat_pump_sink_T: 55. - demand: - profile: - residential: eulp # efs, eulp - commercial: eulp # efs, eulp - transport: efs # efs - industry: efs # efs - scale: - residential: aeo # efs, aeo - commercial: aeo # efs, aeo - transport: aeo # efs, aeo - industry: aeo # efs, aeo - disaggregation: - residential: pop # pop - commercial: pop # pop - transport: pop # pop - industry: pop # pop - scenarios: - aeo: reference - -# docs : -clustering: - simplify_network: - to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. - cluster_network: - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time - aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] - exclude_carriers: [] - consider_efficiency_classes: false - aggregation_strategies: - generators: - committable: any - start_up_cost: 'capacity_weighted_average' - min_up_time: 'capacity_weighted_average' - min_down_time: 'capacity_weighted_average' - ramp_limit_up: max - ramp_limit_down: max - vom_cost: mean - fuel_cost: mean - heat_rate: mean - temporal: - resolution_elec: false - resolution_sector: false - -focus_weights: - -# docs : -solving: - #tmpdir: "path/to/tmp" - options: - load_shedding: false - clip_p_max_pu: 1.e-2 - noisy_costs: true - skip_iterations: true - rolling_horizon: false - seed: 123 - # options that go into the optimize function - track_iterations: false - min_iterations: 4 - max_iterations: 6 - transmission_losses: 2 - linearized_unit_commitment: true - horizon: 8760 - assign_all_duals: true - - - solver: - name: gurobi - options: gurobi-default - - solver_options: - highs-default: - # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver - threads: 4 - solver: "ipm" - run_crossover: "off" - small_matrix_value: 1e-6 - large_matrix_value: 1e9 - primal_feasibility_tolerance: 1e-5 - dual_feasibility_tolerance: 1e-5 - ipm_optimality_tolerance: 1e-4 - parallel: "on" - random_seed: 123 - gurobi-default: - threads: 8 - method: 2 # barrier - crossover: 0 - BarConvTol: 1.e-4 - OptimalityTol: 1.e-4 - FeasibilityTol: 1.e-3 - Seed: 123 - AggFill: 0 - PreDual: 0 - GURO_PAR_BARDENSETHRESH: 200 - gurobi-numeric-focus: - name: gurobi - NumericFocus: 3 # Favour numeric stability over speed - method: 2 # barrier - crossover: 0 # do not use crossover - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-4 - OptimalityTol: 1.e-4 - ObjScale: -0.5 - threads: 8 - Seed: 123 - gurobi-fallback: # Use gurobi defaults - name: gurobi - crossover: 0 - method: 2 # barrier - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-5 - OptimalityTol: 1.e-5 - Seed: 123 - threads: 8 - cplex-default: - threads: 4 - lpmethod: 4 # barrier - solutiontype: 2 # non basic solution, ie no crossover - barrier.convergetol: 1.e-5 - feasopt.tolerance: 1.e-6 - cbc-default: {} # Used in CI - glpk-default: {} # Used in CI - - mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 - walltime: "12:00:00" - - -# docs : -custom_files: - activate: false - files_path: '' - network_name: '' \ No newline at end of file diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml deleted file mode 100644 index 58f4d6a5..00000000 --- a/workflow/config/config.egs.yaml +++ /dev/null @@ -1,288 +0,0 @@ -# PyPSA-USA Default Configuration File - -run: - name: "EGS" # use this to keep track of runs with different settings - disable_progressbar: false # set to true to disable the progressbar - shared_resources: false # set to true to share the default resources across runs - shared_cutouts: true # set to true to share the default cutout(s) across runs - validation: false # set to true to run back-casting plots - -# docs : -scenario: - interconnect: [western] #"usa|texas|western|eastern" - clusters: [33] - simpl: [200] - opts: [REM-2000SEG] - ll: [v1.0] - scope: "total" # "urban", "rural", or "total" - sector: "" # G - planning_horizons: [2030, 2040, 2050] - # - 2030 #(2018-2023, 2030, 2040, 2050) - -foresight: 'perfect' - - -# docs : -enable: - build_cutout: false - -snapshots: - start: "2019-01-01" - end: "2019-12-31" - inclusive: "left" - - -# docs : -electricity: - conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network - renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro, EGS] # Choose the renewable plant types to include in network - voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" - co2limit: 1.4728e+9 # 0.8 * 1.841e+9 - co2limit_enable: false # For sector coupled studies - co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. - gaslimit: false # global gas usage limit of X MWh_th - gaslimit_enable: false # For sector coupled studies - retirement: economic # "economic" or "technical" - SAFE_reservemargin: 0.14 - regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' - agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' - portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' - SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' - transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' - - - operational_reserve: - activate: false - epsilon_load: 0.02 - epsilon_vres: 0.02 - contingency: 4000 - - max_hours: - battery: 6 - H2: 168 - - extendable_carriers: - Generator: [solar, onwind, offwind, offwind_floating, EGS, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR] #offwind, offwind_floating, maybe include CCGT-CCS - StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] - Store: [] - Link: [] - - demand: - profile: efs # efs, eia - scenario: - efs_case: reference # reference, medium, high - efs_speed: moderate # slow, moderate, rapid - aeo: reference - - autarky: - enable: false - by_country: false - -# docs : -conventional: - unit_commitment: false - dynamic_fuel_price: - pudl: true - wholesale: true - -# docs : -lines: - types: # All temporary values, need to be updated - 115.: "Al/St 240/40 2-bundle 220.0" - 138.: "Al/St 240/40 2-bundle 220.0" - 161.: "Al/St 240/40 2-bundle 220.0" - 230.: "Al/St 240/40 2-bundle 220.0" - 345.: "Al/St 240/40 4-bundle 380.0" - 500.: "Al/St 560/50 4-bundle 750.0" - 765.: "Al/St 560/50 4-bundle 750.0" - s_max_pu: 0.7 - s_nom_max: .inf - max_extension: 1000.0e+3 - length_factor: 1.25 - interface_transmission_limits: true - transport_model : true - -# docs : -links: - p_max_pu: 0.7 - p_nom_max: .inf - max_extension: 1000.0e+3 - - -# docs : -costs: - social_discount_rate: 0.02 - version: v0.6.0 - rooftop_share: 0.0 - ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] - fill_values: - FOM: 0 - VOM: 0 - efficiency: 1 - fuel: 0 - investment: 0 - lifetime: 25 - "CO2 intensity": 0 - "discount rate": 0.07 - marginal_cost: - solar: 0.00 - onwind: 0.00 - offwind: 0.00 - hydro: 0. - H2: 0. - electrolysis: 0. - fuel cell: 0. - battery: 0. - battery inverter: 0. - emission_prices: # in currency per tonne emission, only used with the option Ep - enable: false - co2: 0. - co2_monthly_prices: false - -# docs : -sector: - co2_sequestration_potential: 0 - natural_gas: - allow_imports_exports: true # false to be implemented - cyclic_storage: false - heating: - heat_pump_sink_T: 55. - demand: - profile: - residential: eulp # efs, eulp - commercial: eulp # efs, eulp - transport: efs # efs - industry: efs # efs - scale: - residential: aeo # efs, aeo - commercial: aeo # efs, aeo - transport: aeo # efs, aeo - industry: aeo # efs, aeo - disaggregation: - residential: pop # pop - commercial: pop # pop - transport: pop # pop - industry: pop # pop - scenarios: - aeo: reference - -# docs : -clustering: - simplify_network: - to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. - cluster_network: - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time - aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] - exclude_carriers: [] - consider_efficiency_classes: false - aggregation_strategies: - generators: - committable: any - build_year: 'capacity_weighted_average' - lifetime: 'capacity_weighted_average' - start_up_cost: 'capacity_weighted_average' - min_up_time: 'capacity_weighted_average' - min_down_time: 'capacity_weighted_average' - ramp_limit_up: max - ramp_limit_down: max - vom_cost: mean - fuel_cost: mean - heat_rate: mean - temporal: - resolution_elec: false - resolution_sector: false - -focus_weights: - -# docs : -solving: - #tmpdir: "path/to/tmp" - options: - load_shedding: false - clip_p_max_pu: 1.e-2 - noisy_costs: true - skip_iterations: true - rolling_horizon: false - seed: 123 - # options that go into the optimize function - track_iterations: false - min_iterations: 4 - max_iterations: 6 - transmission_losses: 2 - linearized_unit_commitment: true - horizon: 8760 - assign_all_duals: true - - - solver: - name: gurobi - options: gurobi-default - - solver_options: - highs-default: - # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver - threads: 24 - solver: "ipm" - run_crossover: "off" - small_matrix_value: 1e-6 - large_matrix_value: 1e9 - primal_feasibility_tolerance: 1e-5 - dual_feasibility_tolerance: 1e-5 - ipm_optimality_tolerance: 1e-4 - parallel: "on" - random_seed: 123 - gurobi-default: - threads: 24 - method: 2 # barrier - crossover: 0 - BarConvTol: 1.e-4 - OptimalityTol: 1.e-4 - FeasibilityTol: 1.e-3 - Seed: 123 - AggFill: 0 - PreDual: 0 - GURO_PAR_BARDENSETHRESH: 200 - gurobi-numeric-focus: - name: gurobi - NumericFocus: 3 # Favour numeric stability over speed - method: 2 # barrier - crossover: 0 # do not use crossover - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-4 - OptimalityTol: 1.e-4 - ObjScale: -0.5 - threads: 24 - Seed: 123 - gurobi-fallback: # Use gurobi defaults - name: gurobi - crossover: 0 - method: 2 # barrier - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-5 - OptimalityTol: 1.e-5 - Seed: 123 - threads: 24 - cplex-default: - threads: 24 - lpmethod: 4 # barrier - solutiontype: 2 # non basic solution, ie no crossover - barrier.convergetol: 1.e-5 - feasopt.tolerance: 1.e-6 - cbc-default: {} # Used in CI - glpk-default: {} # Used in CI - - mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 - walltime: "24:00:00" - cores: 24 - - -# docs : -custom_files: - activate: false - files_path: '' - network_name: '' \ No newline at end of file diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml deleted file mode 100644 index 882b4414..00000000 --- a/workflow/config/config.mod_default.yaml +++ /dev/null @@ -1,288 +0,0 @@ -# PyPSA-USA Default Configuration File - -run: - name: "Default" # use this to keep track of runs with different settings - disable_progressbar: false # set to true to disable the progressbar - shared_resources: false # set to true to share the default resources across runs - shared_cutouts: true # set to true to share the default cutout(s) across runs - validation: false # set to true to run back-casting plots - -# docs : -scenario: - interconnect: [texas] #"usa|texas|western|eastern" - clusters: [7] - simpl: [200] - opts: [REM-2000SEG] - ll: [v1.0] - scope: "total" # "urban", "rural", or "total" - sector: "" # G - planning_horizons: [2030, 2040, 2050] - # - 2030 #(2018-2023, 2030, 2040, 2050) - -foresight: 'perfect' - - -# docs : -enable: - build_cutout: false - -snapshots: - start: "2019-01-01" - end: "2019-12-31" - inclusive: "left" - - -# docs : -electricity: - conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network - renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network - voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" - co2limit: 1.4728e+9 # 0.8 * 1.841e+9 - co2limit_enable: false # For sector coupled studies - co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. - gaslimit: false # global gas usage limit of X MWh_th - gaslimit_enable: false # For sector coupled studies - retirement: economic # "economic" or "technical" - SAFE_reservemargin: 0.14 - regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' - agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' - portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' - SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' - transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' - - - operational_reserve: - activate: false - epsilon_load: 0.02 - epsilon_vres: 0.02 - contingency: 4000 - - max_hours: - battery: 6 - H2: 168 - - extendable_carriers: - Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR] #offwind, offwind_floating, maybe include CCGT-CCS - StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] - Store: [] - Link: [] - - demand: - profile: efs # efs, eia - scenario: - efs_case: reference # reference, medium, high - efs_speed: moderate # slow, moderate, rapid - aeo: reference - - autarky: - enable: false - by_country: false - -# docs : -conventional: - unit_commitment: false - dynamic_fuel_price: - pudl: true - wholesale: true - -# docs : -lines: - types: # All temporary values, need to be updated - 115.: "Al/St 240/40 2-bundle 220.0" - 138.: "Al/St 240/40 2-bundle 220.0" - 161.: "Al/St 240/40 2-bundle 220.0" - 230.: "Al/St 240/40 2-bundle 220.0" - 345.: "Al/St 240/40 4-bundle 380.0" - 500.: "Al/St 560/50 4-bundle 750.0" - 765.: "Al/St 560/50 4-bundle 750.0" - s_max_pu: 0.7 - s_nom_max: .inf - max_extension: 1000.0e+3 - length_factor: 1.25 - interface_transmission_limits: true - transport_model : true - -# docs : -links: - p_max_pu: 0.7 - p_nom_max: .inf - max_extension: 1000.0e+3 - - -# docs : -costs: - social_discount_rate: 0.02 - version: v0.6.0 - rooftop_share: 0.0 - ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] - fill_values: - FOM: 0 - VOM: 0 - efficiency: 1 - fuel: 0 - investment: 0 - lifetime: 25 - "CO2 intensity": 0 - "discount rate": 0.07 - marginal_cost: - solar: 0.00 - onwind: 0.00 - offwind: 0.00 - hydro: 0. - H2: 0. - electrolysis: 0. - fuel cell: 0. - battery: 0. - battery inverter: 0. - emission_prices: # in currency per tonne emission, only used with the option Ep - enable: false - co2: 0. - co2_monthly_prices: false - -# docs : -sector: - co2_sequestration_potential: 0 - natural_gas: - allow_imports_exports: true # false to be implemented - cyclic_storage: false - heating: - heat_pump_sink_T: 55. - demand: - profile: - residential: eulp # efs, eulp - commercial: eulp # efs, eulp - transport: efs # efs - industry: efs # efs - scale: - residential: aeo # efs, aeo - commercial: aeo # efs, aeo - transport: aeo # efs, aeo - industry: aeo # efs, aeo - disaggregation: - residential: pop # pop - commercial: pop # pop - transport: pop # pop - industry: pop # pop - scenarios: - aeo: reference - -# docs : -clustering: - simplify_network: - to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. - cluster_network: - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time - aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] - exclude_carriers: [] - consider_efficiency_classes: false - aggregation_strategies: - generators: - committable: any - build_year: 'capacity_weighted_average' - lifetime: 'capacity_weighted_average' - start_up_cost: 'capacity_weighted_average' - min_up_time: 'capacity_weighted_average' - min_down_time: 'capacity_weighted_average' - ramp_limit_up: max - ramp_limit_down: max - vom_cost: mean - fuel_cost: mean - heat_rate: mean - temporal: - resolution_elec: false - resolution_sector: false - -focus_weights: - -# docs : -solving: - #tmpdir: "path/to/tmp" - options: - load_shedding: false - clip_p_max_pu: 1.e-2 - noisy_costs: true - skip_iterations: true - rolling_horizon: false - seed: 123 - # options that go into the optimize function - track_iterations: false - min_iterations: 4 - max_iterations: 6 - transmission_losses: 2 - linearized_unit_commitment: true - horizon: 8760 - assign_all_duals: true - - - solver: - name: gurobi - options: gurobi-default - - solver_options: - highs-default: - # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver - threads: 24 - solver: "ipm" - run_crossover: "off" - small_matrix_value: 1e-6 - large_matrix_value: 1e9 - primal_feasibility_tolerance: 1e-5 - dual_feasibility_tolerance: 1e-5 - ipm_optimality_tolerance: 1e-4 - parallel: "on" - random_seed: 123 - gurobi-default: - threads: 24 - method: 2 # barrier - crossover: 0 - BarConvTol: 1.e-4 - OptimalityTol: 1.e-4 - FeasibilityTol: 1.e-3 - Seed: 123 - AggFill: 0 - PreDual: 0 - GURO_PAR_BARDENSETHRESH: 200 - gurobi-numeric-focus: - name: gurobi - NumericFocus: 3 # Favour numeric stability over speed - method: 2 # barrier - crossover: 0 # do not use crossover - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-4 - OptimalityTol: 1.e-4 - ObjScale: -0.5 - threads: 24 - Seed: 123 - gurobi-fallback: # Use gurobi defaults - name: gurobi - crossover: 0 - method: 2 # barrier - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-5 - OptimalityTol: 1.e-5 - Seed: 123 - threads: 24 - cplex-default: - threads: 24 - lpmethod: 4 # barrier - solutiontype: 2 # non basic solution, ie no crossover - barrier.convergetol: 1.e-5 - feasopt.tolerance: 1.e-6 - cbc-default: {} # Used in CI - glpk-default: {} # Used in CI - - mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 - walltime: "24:00:00" - cores: 24 - - -# docs : -custom_files: - activate: false - files_path: '' - network_name: '' \ No newline at end of file diff --git a/workflow/config/config.plotting.yaml b/workflow/config/config.plotting.yaml deleted file mode 100644 index 1332b9a2..00000000 --- a/workflow/config/config.plotting.yaml +++ /dev/null @@ -1,122 +0,0 @@ -plotting: - costs_max: 800 - costs_threshold: 1 - - energy_max: 15000. - energy_min: -10000. - energy_threshold: 50. - - # vre_techs: ["onwind","offwind_floating", "offwind-ac", "offwind-dc", "solar", "ror"] - # conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"] - # storage_techs: ["hydro+PHS", "battery", "H2"] - # load_carriers: ["AC load"] - # AC_carriers: ["AC line", "AC transformer"] - # link_carriers: ["DC line", "Converter AC-DC"] - tech_colors: - "onwind": "#235ebc" - "wind": "#235ebc" - "onshore wind": "#235ebc" - 'offwind': "#dd6895" - 'offshore wind': "#6895dd" - 'offwind-ac': "#6895dd" - 'offshore wind ac': "#6895dd" - 'offwind-dc': "#74c6f2" - 'offshore wind dc': "#74c6f2" - 'offwind_floating': "#11a1c1" - "hydro": "#08ad97" - "hydro+PHS": "#08ad97" - "PHS": "#08ad97" - "hydro reservoir": "#08ad97" - 'hydroelectricity': '#08ad97' - "ror": "#4adbc8" - "run of river": "#4adbc8" - 'solar': "#f9d002" - 'solar PV': "#f9d002" - 'solar thermal': '#ffef60' - 'biomass': '#0c6013' - 'solid biomass': '#06540d' - 'biogas': '#23932d' - 'waste': '#68896b' - 'geothermal': '#ba91b1' - 'EGS': '#DAA520' - "OCGT": "#d35050" - "gas": "#d35050" - "ng": "#d35050" - "natural gas": "#d35050" - "CCGT": "#b20101" - "nuclear": "#ff9000" - "coal": "#707070" - "lignite": "#9e5a01" - "oil": "#262626" - "H2": "#ea048a" - "hydrogen storage": "#ea048a" - "battery": "#b8ea04" - "2hr_battery_storage": "#aee000" - "4hr_battery_storage": "#a4d600" - "6hr_battery_storage": "#9acc00" - "8hr_battery_storage": "#90c200" - "10hr_battery_storage": "#86b800" - "Electric load": "#f9d002" - "electricity": "#f9d002" - "lines": "#70af1d" - "transmission lines": "#70af1d" - "AC-AC": "#70af1d" - "AC line": "#70af1d" - "AC": "#70af1d" - "links": "#8a1caf" - "HVDC links": "#8a1caf" - "DC-DC": "#8a1caf" - "DC link": "#8a1caf" - "DC": "#8a1caf" - "Load": "#2ad55f" - "res-elec": "#f9d002" - "res-heat": "#E79CA2" - "res-cool": "#9CE7E2" - "com-elec": "#f9d002" - "com-heat": "#E79CA2" - "com-cool": "#9CE7E2" - "ind-elec": "#f9d002" - "ind-heat": "#E79CA2" - "trn-elec": "#f9d002" - "coal-95CCS": "#4b4b4b" - "coal-99CCS": "#2e2e2e" - "SMR": "#ff5733" - "CCGT-95CCS": "#800000" - "8hr_PHS": "#069686" - "10hr_PHS": "#058a79" - "12hr_PHS": "#047d6c" - "8hr_PHS_discharger": "#069686" - "10hr_PHS_discharger": "#058a79" - "12hr_PHS_discharger": "#047d6c" - "8hr_PHS_charger": "#069686" - "10hr_PHS_charger": "#058a79" - "12hr_PHS_charger": "#047d6c" - - nice_names: - OCGT: "Open-Cycle Gas" - CCGT: "Combined-Cycle Gas" - offwind: "Fixed Bottom Offshore Wind" - offwind_floating: "Floating Offshore Wind" - onwind: "Onshore Wind" - solar: "Solar" - EGS: "EGS" - coal-99CCS: "Coal-99CCS" - coal-95CCS: "Coal-95CCS" - CCGT-95CCS: "Gas-95CCS" - SMR: "SMR" - PHS: "Pumped Hydro Storage" - hydro: "Reservoir & Dam" - battery: "Battery Storage" - H2: "Hydrogen Storage" - lines: "Transmission Lines" - ror: "Run of River" - Load: "Load Shed" - res-elec: "Residential Electrical" - res-heat: "Residential Heating" - res-cool: "Residential Cooling" - com-elec: "Commercial Electrical" - com-heat: "Commercial Heating" - com-cool: "Commercial Cooling" - ind-elec: "Industrial Electrical" - ind-heat: "Industrial Heating" - trn-elec: "Transportation Electrical" \ No newline at end of file diff --git a/workflow/config/config.tutorial.yaml b/workflow/config/config.tutorial.yaml deleted file mode 100644 index bbd8d56a..00000000 --- a/workflow/config/config.tutorial.yaml +++ /dev/null @@ -1,287 +0,0 @@ -# PyPSA-USA Default Configuration File - -run: - name: "Tutorial" # use this to keep track of runs with different settings - disable_progressbar: false # set to true to disable the progressbar - shared_resources: false # set to true to share the default resources across runs - shared_cutouts: true # set to true to share the default cutout(s) across runs - validation: false # set to true to run back-casting plots - -# docs : -scenario: - interconnect: [texas] #"usa|texas|western|eastern" - clusters: [20] - opts: [REM-1000SEG] - ll: [v1.05] - scope: "total" # "urban", "rural", or "total" - sector: "" # G - planning_horizons: - - 2030 #(2018-2023, 2030, 2040, 2050) - -foresight: 'perfect' - - -# docs : -enable: - build_cutout: false - -snapshots: # Defines renewable weather year, and annual snapshot time-scope - start: "2019-01-01" - end: "2019-02-01" - inclusive: "left" - - -# docs : -electricity: - conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network - renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network - voltage_simplified: 230 - co2limit: 180.3e+3 - co2limit_enable: true - co2base: 180.3e+6 - gaslimit: false # global gas usage limit of X MWh_th - gaslimit_enable: false - retirement: economic # "economic" or "technical" - SAFE_reservemargin: 0.14 - regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' - agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' - portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' - SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' - transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' - - operational_reserve: - activate: false - epsilon_load: 0.02 - epsilon_vres: 0.02 - contingency: 4000 - - max_hours: - battery: 6 - H2: 168 - - extendable_carriers: - Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired - StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] - Store: [] - Link: [] - - demand: #EFS used for given planning_horizons year (only ref/mod implemented) - EFS_case: reference # reference, medium, high - EFS_speed: moderate # slow, moderate, rapid - - autarky: - enable: false - by_country: false - -# docs : -conventional: - unit_commitment: false - dynamic_fuel_price: - pudl: true - wholesale: true - -# docs : -lines: - types: # All temporary values, need to be updated - 115.: "Al/St 240/40 2-bundle 220.0" - 138.: "Al/St 240/40 2-bundle 220.0" - 161.: "Al/St 240/40 2-bundle 220.0" - 230.: "Al/St 240/40 2-bundle 220.0" - 345.: "Al/St 240/40 4-bundle 380.0" - 500.: "Al/St 560/50 4-bundle 750.0" - 765.: "Al/St 560/50 4-bundle 750.0" - s_max_pu: 0.7 - s_nom_max: .inf - max_extension: 1000.0e+3 - length_factor: 1.25 - interface_transmission_limits: true # Imposes ITLs over AC Lines - transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs - - -# docs : -links: - p_max_pu: 1.0 - p_nom_max: .inf - max_extension: 1000.0e+3 - -# docs : -load: - scaling_factor: 1.0 - -# docs : -costs: - social_discount_rate: 0.02 - version: v0.6.0 - rooftop_share: 0.0 - ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] - fill_values: - FOM: 0 - VOM: 0 - efficiency: 1 - fuel: 0 - investment: 0 - lifetime: 25 - "CO2 intensity": 0 - "discount rate": 0.07 - marginal_cost: - solar: 0.00 - onwind: 0.00 - offwind: 0.00 - hydro: 0. - H2: 0. - electrolysis: 0. - fuel cell: 0. - battery: 0. - battery inverter: 0. - emission_prices: # in currency per tonne emission, only used with the option Ep - enable: false - co2: 0. - co2_monthly_prices: false - ptc_modifier: - onwind: 18.2547 - geothermal: 18.2547 - biomass: 18.2547 - itc_modifier: - solar: 0.3 - offwind: 0.3 - offwind_floating: 0.3 - EGS: 0.3 - - -# docs : -sector: - co2_sequestration_potential: 0 - natural_gas: - allow_imports_exports: true # false to be implemented - cyclic_storage: false - heating: - heat_pump_sink_T: 55. - demand: - profile: - residential: eulp # efs, eulp - commercial: eulp # efs, eulp - transport: efs # efs - industry: efs # efs - scale: - residential: aeo # efs, aeo - commercial: aeo # efs, aeo - transport: aeo # efs, aeo - industry: aeo # efs, aeo - disaggregation: - residential: pop # pop - commercial: pop # pop - transport: pop # pop - industry: pop # pop - scenarios: - aeo: reference - -# docs : -clustering: - simplify_network: - to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. - cluster_network: - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time - aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] - exclude_carriers: [] - consider_efficiency_classes: false - aggregation_strategies: - generators: - committable: any - ramp_limit_up: max - ramp_limit_down: max - # Mean heat-rates, VOM, and fuel are not used in the model, only for post processing purposes - vom_cost: mean - fuel_cost: mean - heat_rate: mean - temporal: - resolution_elec: false - resolution_sector: false - -focus_weights: - # California: 0.5 - - -# docs : -solving: - #tmpdir: "path/to/tmp" - options: - load_shedding: false - clip_p_max_pu: 1.e-2 - noisy_costs: true - skip_iterations: true - rolling_horizon: false - seed: 123 - # options that go into the optimize function - track_iterations: false - min_iterations: 4 - max_iterations: 6 - transmission_losses: 2 - linearized_unit_commitment: true - horizon: 8760 - assign_all_duals: true - - - solver: - name: gurobi - options: gurobi-default - - solver_options: - highs-default: - # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver - threads: 4 - solver: "ipm" - run_crossover: "off" - small_matrix_value: 1e-6 - large_matrix_value: 1e9 - primal_feasibility_tolerance: 1e-5 - dual_feasibility_tolerance: 1e-5 - ipm_optimality_tolerance: 1e-4 - parallel: "on" - random_seed: 123 - gurobi-default: - threads: 8 - method: 2 # barrier - crossover: 0 - BarConvTol: 1.e-4 - OptimalityTol: 1.e-4 - FeasibilityTol: 1.e-3 - Seed: 123 - AggFill: 0 - PreDual: 0 - GURO_PAR_BARDENSETHRESH: 200 - gurobi-numeric-focus: - name: gurobi - NumericFocus: 3 # Favour numeric stability over speed - method: 2 # barrier - crossover: 0 # do not use crossover - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-4 - OptimalityTol: 1.e-4 - ObjScale: -0.5 - threads: 8 - Seed: 123 - gurobi-fallback: # Use gurobi defaults - name: gurobi - crossover: 0 - method: 2 # barrier - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-5 - OptimalityTol: 1.e-5 - Seed: 123 - threads: 8 - cplex-default: - threads: 4 - lpmethod: 4 # barrier - solutiontype: 2 # non basic solution, ie no crossover - barrier.convergetol: 1.e-5 - feasopt.tolerance: 1.e-6 - cbc-default: {} # Used in CI - glpk-default: {} # Used in CI - - mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 - walltime: "12:00:00" diff --git a/workflow/config/config.validation.yaml b/workflow/config/config.validation.yaml deleted file mode 100644 index 44eed3dd..00000000 --- a/workflow/config/config.validation.yaml +++ /dev/null @@ -1,284 +0,0 @@ -# PyPSA-USA Validation Configuration File - -run: - name: "Validation_REEDS" # use this to keep track of runs with different settings - disable_progressbar: false # set to true to disable the progressbar - shared_resources: false # set to true to share the default resources across runs - shared_cutouts: true # set to true to share the default cutout(s) across runs - validation: true # set to true to run back-casting plots - -# docs : -scenario: - interconnect: [western] #"usa|texas|western|eastern" - clusters: [40] - opts: [Ep] - ll: [v1.0] - scope: "total" # "urban", "rural", or "total" - sector: "" # G - planning_horizons: - - 2019 #(2018-2023) - -foresight: 'perfect' - -# docs : -enable: - build_cutout: false - -snapshots: - start: "2019-01-01" - end: "2020-01-01" - inclusive: 'left' - -# docs : -electricity: - conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network - renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network - voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" - co2limit: 1.4728e+9 # 0.8 * 1.841e+9 - co2limit_enable: false # For sector coupled studies - co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. - gaslimit: false # global gas usage limit of X MWh_th - gaslimit_enable: false # For sector coupled studies - retirement: economic # "economic" or "technical" - SAFE_reservemargin: 0.14 - regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' - agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' - portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' - SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' - transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' - - operational_reserve: - activate: false - epsilon_load: 0.02 - epsilon_vres: 0.02 - contingency: 4000 - - max_hours: - battery: 6 - H2: 168 - - extendable_carriers: - Generator: [] - StorageUnit: [] - Store: [] - Link: [] - - demand: - profile: eia # efs, eia - scale: 1 # efs, aeo, or a number - disaggregation: pop # pop - scenario: - efs_case: reference # reference, medium, high - efs_speed: moderate # slow, moderate, rapid - aeo: reference - - autarky: - enable: false - by_country: false - -# docs : -conventional: - unit_commitment: false - dynamic_fuel_price: - pudl: true - wholesale: true - -# docs : -lines: - types: # All temporary values, need to be updated - 115.: "Al/St 240/40 2-bundle 220.0" - 138.: "Al/St 240/40 2-bundle 220.0" - 161.: "Al/St 240/40 2-bundle 220.0" - 230.: "Al/St 240/40 2-bundle 220.0" - 345.: "Al/St 240/40 4-bundle 380.0" - 500.: "Al/St 560/50 4-bundle 750.0" - 765.: "Al/St 560/50 4-bundle 750.0" - s_max_pu: 0.7 - s_nom_max: .inf - length_factor: 1.25 - interface_transmission_limits: true # Imposes ITLs over AC Lines - transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs - -# docs : -links: - p_max_pu: 0.7 - p_nom_max: .inf - -# docs : -load: - scaling_factor: 1.0 - -# docs : -costs: - social_discount_rate: 0.02 - version: v0.6.0 - rooftop_share: 0.0 - ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] - fill_values: - FOM: 0 - VOM: 0 - efficiency: 1 - fuel: 0 - investment: 0 - lifetime: 25 - "CO2 intensity": 0 - "discount rate": 0.07 - marginal_cost: - solar: 0.00 - onwind: 0.00 - offwind: 0.00 - hydro: 0. - H2: 0. - electrolysis: 0. - fuel cell: 0. - battery: 0. - battery inverter: 0. - emission_prices: # in currency per tonne emission, only used with the option Ep - enable: false - co2: 0. - co2_monthly_prices: false - -# docs : -sector: - co2_sequestration_potential: 0 - natural_gas: - allow_imports_exports: true # false to be implemented - cyclic_storage: false - heating: - heat_pump_sink_T: 55. - demand: - profile: - residential: eulp # efs, eulp - commercial: eulp # efs, eulp - transport: efs # efs - industry: efs # efs - scale: - residential: aeo # efs, aeo - commercial: aeo # efs, aeo - transport: aeo # efs, aeo - industry: aeo # efs, aeo - disaggregation: - residential: pop # pop - commercial: pop # pop - transport: pop # pop - industry: pop # pop - scenarios: - aeo: reference - -# docs : -clustering: - simplify_network: - to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) - algorithm: kmeans # choose from: [hac, kmeans] - feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. - cluster_network: - algorithm: kmeans - feature: solar+onwind-time - aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] - exclude_carriers: [] - consider_efficiency_classes: False - aggregation_strategies: - generators: - committable: any - start_up_cost: 'capacity_weighted_average' - min_up_time: 'capacity_weighted_average' - min_down_time: 'capacity_weighted_average' - ramp_limit_up: max - ramp_limit_down: max - vom_cost: mean - fuel_cost: mean - heat_rate: mean - temporal: - resolution_elec: false - resolution_sector: false - -focus_weights: - -# docs : -solving: - #tmpdir: "path/to/tmp" - options: - load_shedding: true - clip_p_max_pu: 1.e-2 - noisy_costs: true - skip_iterations: true - rolling_horizon: false - seed: 123 - # options that go into the optimize function - track_iterations: false - min_iterations: 4 - max_iterations: 6 - transmission_losses: 2 - linearized_unit_commitment: true - horizon: 8760 - assign_all_duals: true - - - solver: - name: gurobi - options: gurobi-default - - solver_options: - highs-default: - # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver - threads: 4 - solver: "ipm" - run_crossover: "off" - small_matrix_value: 1e-6 - large_matrix_value: 1e9 - primal_feasibility_tolerance: 1e-5 - dual_feasibility_tolerance: 1e-5 - ipm_optimality_tolerance: 1e-4 - parallel: "on" - random_seed: 123 - gurobi-default: - threads: 32 - method: 2 # barrier - crossover: 0 - BarConvTol: 1.e-4 - OptimalityTol: 1.e-4 - FeasibilityTol: 1.e-3 - Seed: 123 - AggFill: 0 - PreDual: 0 - GURO_PAR_BARDENSETHRESH: 200 - gurobi-numeric-focus: - name: gurobi - NumericFocus: 3 # Favour numeric stability over speed - method: 2 # barrier - crossover: 0 # do not use crossover - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-4 - OptimalityTol: 1.e-4 - ObjScale: -0.5 - threads: 8 - Seed: 123 - gurobi-fallback: # Use gurobi defaults - name: gurobi - crossover: 0 - method: 2 # barrier - BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-5 - OptimalityTol: 1.e-5 - Seed: 123 - threads: 8 - cplex-default: - threads: 4 - lpmethod: 4 # barrier - solutiontype: 2 # non basic solution, ie no crossover - barrier.convergetol: 1.e-5 - feasopt.tolerance: 1.e-6 - cbc-default: {} # Used in CI - glpk-default: {} # Used in CI - - mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 - walltime: "12:00:00" - - -# docs : -custom_files: - activate: false - files_path: '/Users/kamrantehranchi/Local_Documents/pypsa-usa/workflow/resources/CustomFiles/' - network_name: 'elec_s_40_ec.nc' \ No newline at end of file diff --git a/workflow/config/policy_constraints/.DS_Store b/workflow/config/policy_constraints/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Mon, 19 Aug 2024 06:59:41 -0700 Subject: [PATCH 13/17] update repo_data --- workflow/repo_data/config/config.api.yaml | 2 +- workflow/repo_data/config/config.cluster.yaml | 20 +++++++++--------- workflow/repo_data/config/config.common.yaml | 21 +++++++++++++++++++ .../repo_data/config/config.plotting.yaml | 6 ++++++ 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/workflow/repo_data/config/config.api.yaml b/workflow/repo_data/config/config.api.yaml index 65e8336d..eb7afdee 100644 --- a/workflow/repo_data/config/config.api.yaml +++ b/workflow/repo_data/config/config.api.yaml @@ -1,4 +1,4 @@ # holds user api keys api: - eia: + eia: kWdnW4WaIeeq2bsihF75w06C1FKiavVVg6he0CT7 diff --git a/workflow/repo_data/config/config.cluster.yaml b/workflow/repo_data/config/config.cluster.yaml index 92186ca1..47af4823 100644 --- a/workflow/repo_data/config/config.cluster.yaml +++ b/workflow/repo_data/config/config.cluster.yaml @@ -1,29 +1,29 @@ __default__: - account: iazevedo + account: horne partition: serc - email: ktehranchi@stanford.edu - walltime: 00:30:00 # time limit for each job + email: m.j.aljubran@gmail.com + walltime: "04:00:00" # time limit for each job cpus_per_task: 1 # number of cores per job - chdir: $GROUP_HOME/kamran/pypsa-usa/workflow + chdir: $GROUP_SCRATCH/aljubrmj/framework_4/hl_markets/pypsa-usa/workflow/ output: logs/{rule}/log-%j.out error: logs/{rule}/errlog-%j.err build_renewable_profiles: - walltime: 02:00:00 + walltime: "24:00:00" add_electricity: - walltime: 02:00:00 + walltime: "24:00:00" simplify_network: - walltime: 02:00:00 + walltime: "24:00:00" cluster_network: - walltime: 02:00:00 + walltime: "24:00:00" solve_network: - walltime: 06:00:00 + walltime: "24:00:00" solve_network_validation: - walltime: 06:00:00 + walltime: "24:00:00" diff --git a/workflow/repo_data/config/config.common.yaml b/workflow/repo_data/config/config.common.yaml index 2b0f9bd5..3a665958 100644 --- a/workflow/repo_data/config/config.common.yaml +++ b/workflow/repo_data/config/config.common.yaml @@ -132,3 +132,24 @@ offshore_shape: offshore_network: enable: true # set to true to enable offshore network bus_spacing: 25000 # km + +costs: + itc_modifier: + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + geothermal: 0.3 + SMR: 0.3 + nuclear: 0.3 + hydro: 0.3 + 4hr_battery_storage: 0.3 + 6hr_battery_storage: 0.3 + 8hr_battery_storage: 0.3 + 10hr_battery_storage: 0.3 + 8hr_PHS: 0.3 + 10hr_PHS: 0.3 + 12hr_PHS: 0.3 + ptc_modifier: + solar: 27.5 + onwind: 27.5 + biomass: 27.5 \ No newline at end of file diff --git a/workflow/repo_data/config/config.plotting.yaml b/workflow/repo_data/config/config.plotting.yaml index c4a8606e..1332b9a2 100644 --- a/workflow/repo_data/config/config.plotting.yaml +++ b/workflow/repo_data/config/config.plotting.yaml @@ -38,6 +38,7 @@ plotting: 'biogas': '#23932d' 'waste': '#68896b' 'geothermal': '#ba91b1' + 'EGS': '#DAA520' "OCGT": "#d35050" "gas": "#d35050" "ng": "#d35050" @@ -98,6 +99,11 @@ plotting: offwind_floating: "Floating Offshore Wind" onwind: "Onshore Wind" solar: "Solar" + EGS: "EGS" + coal-99CCS: "Coal-99CCS" + coal-95CCS: "Coal-95CCS" + CCGT-95CCS: "Gas-95CCS" + SMR: "SMR" PHS: "Pumped Hydro Storage" hydro: "Reservoir & Dam" battery: "Battery Storage" From 17f247edc10ef23cd565545347c8e68606c1356a Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Mon, 19 Aug 2024 07:01:45 -0700 Subject: [PATCH 14/17] update repo_data --- workflow/repo_data/config/config.api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow/repo_data/config/config.api.yaml b/workflow/repo_data/config/config.api.yaml index eb7afdee..65e8336d 100644 --- a/workflow/repo_data/config/config.api.yaml +++ b/workflow/repo_data/config/config.api.yaml @@ -1,4 +1,4 @@ # holds user api keys api: - eia: kWdnW4WaIeeq2bsihF75w06C1FKiavVVg6he0CT7 + eia: From 7f6ce1cead35bf081d1c7fc7bed94b74b664856e Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:44:20 -0700 Subject: [PATCH 15/17] activate land-use constraint --- workflow/rules/common.smk | 2 +- workflow/scripts/solve_network.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/workflow/rules/common.smk b/workflow/rules/common.smk index fec1d904..5f2acd92 100644 --- a/workflow/rules/common.smk +++ b/workflow/rules/common.smk @@ -131,7 +131,7 @@ def interconnect_mem_a(w): def interconnect_mem_s(w): - mem = 15000 * len(config_provider("scenario", "planning_horizons")(w)) + mem = 30000 * len(config_provider("scenario", "planning_horizons")(w)) if w.interconnect == "usa": return int(mem * 4) elif w.interconnect == "eastern": diff --git a/workflow/scripts/solve_network.py b/workflow/scripts/solve_network.py index a4d6e2d1..57612a36 100644 --- a/workflow/scripts/solve_network.py +++ b/workflow/scripts/solve_network.py @@ -77,7 +77,7 @@ def check_p_min_p_max(p_nom_max): f"summed p_min_pu values at node larger than technical potential {check[check].index}", ) - grouper = [n.generators.carrier, n.generators.bus, n.generators.build_year] + grouper = [n.generators.carrier, n.generators.bus]#, n.generators.build_year] ext_i = n.generators.p_nom_extendable & ~n.generators.index.str.contains("existing") # get technical limit per node and investment period p_nom_max = n.generators[ext_i].groupby(grouper).min().p_nom_max @@ -95,7 +95,7 @@ def check_p_min_p_max(p_nom_max): df = p_nom_max.reset_index() df["name"] = df.apply( lambda row: f"nom_max_{row['carrier']}" - + (f"_{row['build_year']}" if row["build_year"] is not None else ""), + + (f"_{row['build_year']}" if row.get["build_year"] is not None else ""), axis=1, ) @@ -188,8 +188,8 @@ def prepare_network( n.set_snapshots(n.snapshots[:nhours]) n.snapshot_weightings[:] = 8760.0 / nhours - # if foresight == "perfect": - # n = add_land_use_constraint_perfect(n) + if foresight == "perfect": + n = add_land_use_constraint_perfect(n) # # if snakemake.params["sector"]["limit_max_growth"]["enable"]: # # n = add_max_growth(n) From b0ab5a5139fd65aa90b901865dc2691759a04d9e Mon Sep 17 00:00:00 2001 From: "Mohammad (Jabs)" <44715677+aljubrmj@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:50:29 -0700 Subject: [PATCH 16/17] add config folder --- workflow/config/config.api.yaml | 4 + workflow/config/config.cluster.yaml | 29 + workflow/config/config.common.yaml | 155 ++ workflow/config/config.default.yaml | 295 ++++ workflow/config/config.egs.yaml | 288 ++++ workflow/config/config.mod_default.yaml | 288 ++++ workflow/config/config.plotting.yaml | 122 ++ workflow/config/config.tutorial.yaml | 287 ++++ workflow/config/config.validation.yaml | 284 ++++ workflow/config/policy_constraints/.DS_Store | Bin 0 -> 6148 bytes .../policy_constraints/SAFE_regional_prm.csv | 2 + .../policy_constraints/agg_p_nom_minmax.csv | 2 + .../portfolio_standards.csv | 2 + .../policy_constraints/reeds/ces_fraction.csv | 17 + .../reeds/offshore_req_30by30.csv | 15 + .../reeds/offshore_req_default.csv | 10 + .../policy_constraints/reeds/prm_annual.csv | 311 ++++ .../policy_constraints/reeds/rggi_states.csv | 12 + .../policy_constraints/reeds/rggicon.csv | 41 + .../policy_constraints/reeds/rps_fraction.csv | 1307 +++++++++++++++++ .../reeds/storage_mandates.csv | 276 ++++ .../regional_Co2_limits.csv | 54 + .../transmission_interface_limits.csv | 4 + 23 files changed, 3805 insertions(+) create mode 100644 workflow/config/config.api.yaml create mode 100644 workflow/config/config.cluster.yaml create mode 100644 workflow/config/config.common.yaml create mode 100644 workflow/config/config.default.yaml create mode 100644 workflow/config/config.egs.yaml create mode 100644 workflow/config/config.mod_default.yaml create mode 100644 workflow/config/config.plotting.yaml create mode 100644 workflow/config/config.tutorial.yaml create mode 100644 workflow/config/config.validation.yaml create mode 100644 workflow/config/policy_constraints/.DS_Store create mode 100644 workflow/config/policy_constraints/SAFE_regional_prm.csv create mode 100644 workflow/config/policy_constraints/agg_p_nom_minmax.csv create mode 100644 workflow/config/policy_constraints/portfolio_standards.csv create mode 100644 workflow/config/policy_constraints/reeds/ces_fraction.csv create mode 100644 workflow/config/policy_constraints/reeds/offshore_req_30by30.csv create mode 100644 workflow/config/policy_constraints/reeds/offshore_req_default.csv create mode 100644 workflow/config/policy_constraints/reeds/prm_annual.csv create mode 100644 workflow/config/policy_constraints/reeds/rggi_states.csv create mode 100644 workflow/config/policy_constraints/reeds/rggicon.csv create mode 100644 workflow/config/policy_constraints/reeds/rps_fraction.csv create mode 100644 workflow/config/policy_constraints/reeds/storage_mandates.csv create mode 100644 workflow/config/policy_constraints/regional_Co2_limits.csv create mode 100644 workflow/config/policy_constraints/transmission_interface_limits.csv diff --git a/workflow/config/config.api.yaml b/workflow/config/config.api.yaml new file mode 100644 index 00000000..eb7afdee --- /dev/null +++ b/workflow/config/config.api.yaml @@ -0,0 +1,4 @@ +# holds user api keys + +api: + eia: kWdnW4WaIeeq2bsihF75w06C1FKiavVVg6he0CT7 diff --git a/workflow/config/config.cluster.yaml b/workflow/config/config.cluster.yaml new file mode 100644 index 00000000..47af4823 --- /dev/null +++ b/workflow/config/config.cluster.yaml @@ -0,0 +1,29 @@ +__default__: + account: horne + partition: serc + email: m.j.aljubran@gmail.com + walltime: "04:00:00" # time limit for each job + cpus_per_task: 1 # number of cores per job + chdir: $GROUP_SCRATCH/aljubrmj/framework_4/hl_markets/pypsa-usa/workflow/ + output: logs/{rule}/log-%j.out + error: logs/{rule}/errlog-%j.err + + + +build_renewable_profiles: + walltime: "24:00:00" + +add_electricity: + walltime: "24:00:00" + +simplify_network: + walltime: "24:00:00" + +cluster_network: + walltime: "24:00:00" + +solve_network: + walltime: "24:00:00" + +solve_network_validation: + walltime: "24:00:00" diff --git a/workflow/config/config.common.yaml b/workflow/config/config.common.yaml new file mode 100644 index 00000000..3a665958 --- /dev/null +++ b/workflow/config/config.common.yaml @@ -0,0 +1,155 @@ + +countries: [US] + +network_configuration: "pypsa-usa" # "pypsa-usa" or "ads2032" + + +# docs : +renewable: + onwind: + cutout: era5_2019 + resource: + method: wind + turbine: Vestas_V112_3MW + add_cutout_windspeed: true + capacity_per_sqkm: 3 # conservative, ScholzPhd Tab 4.3.1: 10MW/km^2 + correction_factor: 1 # 0.93 + corine: + #all keys labeled corrine are actually copernicus codes. Using the name corrine bc using the pypsa-eur convention: https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf + grid_codes: [20, 30, 40, 60, 100, 112, 113, 114, 115] + distance: 10 #buffer from distance_grid_codes that are to be excluded + distance_grid_codes: [50] + natura: true + cec: true + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + offwind: + cutout: era5_2019 + resource: + method: wind + turbine: NREL_ReferenceTurbine_2020ATB_5.5MW + # add_cutout_windspeed: true + capacity_per_sqkm: 3 # 2021–2022 Transmission Plan, CAISO + correction_factor: 1 # 0.8855 # proxy for wake losses, from 10.1016/j.energy.2018.08.153 + corine: + grid_codes: [80, 200] #page 28 of https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf + natura: true + boem_screen: true + max_depth: 60 # meters, ref https://www.nrel.gov/docs/fy16osti/66599.pdf + min_shore_distance: 22000 # meters + max_shore_distance: 65000 # meters + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + offwind_floating: + cutout: era5_2019 + resource: + method: wind + turbine: NREL_ReferenceTurbine_2020ATB_15MW_offshore + add_cutout_windspeed: true + capacity_per_sqkm: 3 # 2021–2022 Transmission Plan, CAISO + correction_factor: 1 # 0.8855 # proxy for wake losses, from 10.1016/j.energy.2018.08.153 + corine: + grid_codes: [80, 200] #page 28 of https://land.copernicus.eu/global/sites/cgls.vito.be/files/products/CGLOPS1_PUM_LC100m-V3_I3.4.pdf + natura: true + boem_screen: true + min_depth: 60 # meters, ref https://www.nrel.gov/docs/fy16osti/66599.pdf + max_depth: 1300 # meters, ref https://www.nrel.gov/docs/fy22osti/83650.pdf + min_shore_distance: 22000 # meters + max_shore_distance: 65000 # meters + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + solar: + cutout: era5_2019 + resource: + method: pv + panel: CSi + orientation: latitude_optimal # will lead into optimal + capacity_per_sqkm: 4.6 # From 1.7 to 4.6 addresses issue #361 - TODO revisit this assumption + correction_factor: 1 # 0.854337 + corine: + grid_codes: [20, 30, 40, 60, 90, 100] #see above for codes + natura: true + cec: true + potential: conservative # simple or conservative + clip_p_max_pu: 1.e-2 + extendable: true + hydro: + cutout: era5_2019 + carriers: [ror, PHS, hydro] + PHS_max_hours: 6 + resource: + method: hydro + hydrobasins: resources/hybas_na_lev06_v1c.shp + flowspeed: 1.0 # m/s + hydro_max_hours: "energy_capacity_totals_by_country" # not active + clip_min_inflow: 1.0 + extendable: true + normalization: + method: hydro_capacities + year: 2013 + multiplier: 1.1 # multiplier applied after the normalization of the hydro production; default 1.0 + + +# docs : +atlite: + default_cutout: era5_2019 + nprocesses: 8 + show_progress: false # false saves time + cutouts: + era5_2019: + module: era5 # in priority order + time: ['2019', '2019'] + interconnects: + western: + x: [-126, -99] + y: [27, 50] + dx: 0.3 + dy: 0.3 + eastern: + x: [-109, -65] + y: [23, 50] + dx: 0.3 + dy: 0.3 + texas: + x: [-110, -90] + y: [24, 37] + dx: 0.3 + dy: 0.3 + usa: + x: [-126, -65] + y: [23, 50] + dx: 0.3 + dy: 0.3 + + +# docs : +offshore_shape: + use: eez #options are ca_osw, eez + +offshore_network: + enable: true # set to true to enable offshore network + bus_spacing: 25000 # km + +costs: + itc_modifier: + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + geothermal: 0.3 + SMR: 0.3 + nuclear: 0.3 + hydro: 0.3 + 4hr_battery_storage: 0.3 + 6hr_battery_storage: 0.3 + 8hr_battery_storage: 0.3 + 10hr_battery_storage: 0.3 + 8hr_PHS: 0.3 + 10hr_PHS: 0.3 + 12hr_PHS: 0.3 + ptc_modifier: + solar: 27.5 + onwind: 27.5 + biomass: 27.5 \ No newline at end of file diff --git a/workflow/config/config.default.yaml b/workflow/config/config.default.yaml new file mode 100644 index 00000000..877e0dd6 --- /dev/null +++ b/workflow/config/config.default.yaml @@ -0,0 +1,295 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Default" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [western] #"usa|texas|western|eastern" + clusters: [40] + opts: [REM-1000SEG] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: + - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2020-01-01" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 + co2limit_enable: false + co2base: 226.86e+6 + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired + StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] + Store: [] + Link: [] + + demand: + profile: eia # efs, eia + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true # Imposes ITLs over AC Lines + transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs + + +# docs : +links: + p_max_pu: 1.0 + p_nom_max: .inf + max_extension: 1000.0e+3 + + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + ptc_modifier: + onwind: 18.2547 + geothermal: 18.2547 + biomass: 18.2547 + itc_modifier: + solar: 0.3 + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 4 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 8 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 8 + cplex-default: + threads: 4 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "12:00:00" + + +# docs : +custom_files: + activate: false + files_path: '' + network_name: '' \ No newline at end of file diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml new file mode 100644 index 00000000..c4da598e --- /dev/null +++ b/workflow/config/config.egs.yaml @@ -0,0 +1,288 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Default" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [texas] #"usa|texas|western|eastern" + clusters: [7] + simpl: [200] + opts: [REM-2000SEG] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: [2030, 2040, 2050] + # - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2019-12-31" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro, EGS] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 # 0.8 * 1.841e+9 + co2limit_enable: false # For sector coupled studies + co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false # For sector coupled studies + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR, nuclear, EGS] #offwind, offwind_floating, maybe include CCGT-CCS + StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] + Store: [] + Link: [] + + demand: + profile: efs # efs, eia + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true + transport_model : true + +# docs : +links: + p_max_pu: 0.7 + p_nom_max: .inf + max_extension: 1000.0e+3 + + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + build_year: 'capacity_weighted_average' + lifetime: 'capacity_weighted_average' + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 24 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 24 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 24 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 24 + cplex-default: + threads: 24 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "24:00:00" + cores: 24 + + +# docs : +custom_files: + activate: false + files_path: '' + network_name: '' \ No newline at end of file diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml new file mode 100644 index 00000000..05617bb9 --- /dev/null +++ b/workflow/config/config.mod_default.yaml @@ -0,0 +1,288 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Default" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [texas] #"usa|texas|western|eastern" + clusters: [7] + simpl: [200] + opts: [REM-2000SEG] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: [2030, 2040, 2050] + # - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2019-12-31" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 # 0.8 * 1.841e+9 + co2limit_enable: false # For sector coupled studies + co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false # For sector coupled studies + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR, nuclear] #offwind, offwind_floating, maybe include CCGT-CCS + StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] + Store: [] + Link: [] + + demand: + profile: efs # efs, eia + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true + transport_model : true + +# docs : +links: + p_max_pu: 0.7 + p_nom_max: .inf + max_extension: 1000.0e+3 + + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + build_year: 'capacity_weighted_average' + lifetime: 'capacity_weighted_average' + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 24 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 24 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 24 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 24 + cplex-default: + threads: 24 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "24:00:00" + cores: 24 + + +# docs : +custom_files: + activate: false + files_path: '' + network_name: '' \ No newline at end of file diff --git a/workflow/config/config.plotting.yaml b/workflow/config/config.plotting.yaml new file mode 100644 index 00000000..1332b9a2 --- /dev/null +++ b/workflow/config/config.plotting.yaml @@ -0,0 +1,122 @@ +plotting: + costs_max: 800 + costs_threshold: 1 + + energy_max: 15000. + energy_min: -10000. + energy_threshold: 50. + + # vre_techs: ["onwind","offwind_floating", "offwind-ac", "offwind-dc", "solar", "ror"] + # conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"] + # storage_techs: ["hydro+PHS", "battery", "H2"] + # load_carriers: ["AC load"] + # AC_carriers: ["AC line", "AC transformer"] + # link_carriers: ["DC line", "Converter AC-DC"] + tech_colors: + "onwind": "#235ebc" + "wind": "#235ebc" + "onshore wind": "#235ebc" + 'offwind': "#dd6895" + 'offshore wind': "#6895dd" + 'offwind-ac': "#6895dd" + 'offshore wind ac': "#6895dd" + 'offwind-dc': "#74c6f2" + 'offshore wind dc': "#74c6f2" + 'offwind_floating': "#11a1c1" + "hydro": "#08ad97" + "hydro+PHS": "#08ad97" + "PHS": "#08ad97" + "hydro reservoir": "#08ad97" + 'hydroelectricity': '#08ad97' + "ror": "#4adbc8" + "run of river": "#4adbc8" + 'solar': "#f9d002" + 'solar PV': "#f9d002" + 'solar thermal': '#ffef60' + 'biomass': '#0c6013' + 'solid biomass': '#06540d' + 'biogas': '#23932d' + 'waste': '#68896b' + 'geothermal': '#ba91b1' + 'EGS': '#DAA520' + "OCGT": "#d35050" + "gas": "#d35050" + "ng": "#d35050" + "natural gas": "#d35050" + "CCGT": "#b20101" + "nuclear": "#ff9000" + "coal": "#707070" + "lignite": "#9e5a01" + "oil": "#262626" + "H2": "#ea048a" + "hydrogen storage": "#ea048a" + "battery": "#b8ea04" + "2hr_battery_storage": "#aee000" + "4hr_battery_storage": "#a4d600" + "6hr_battery_storage": "#9acc00" + "8hr_battery_storage": "#90c200" + "10hr_battery_storage": "#86b800" + "Electric load": "#f9d002" + "electricity": "#f9d002" + "lines": "#70af1d" + "transmission lines": "#70af1d" + "AC-AC": "#70af1d" + "AC line": "#70af1d" + "AC": "#70af1d" + "links": "#8a1caf" + "HVDC links": "#8a1caf" + "DC-DC": "#8a1caf" + "DC link": "#8a1caf" + "DC": "#8a1caf" + "Load": "#2ad55f" + "res-elec": "#f9d002" + "res-heat": "#E79CA2" + "res-cool": "#9CE7E2" + "com-elec": "#f9d002" + "com-heat": "#E79CA2" + "com-cool": "#9CE7E2" + "ind-elec": "#f9d002" + "ind-heat": "#E79CA2" + "trn-elec": "#f9d002" + "coal-95CCS": "#4b4b4b" + "coal-99CCS": "#2e2e2e" + "SMR": "#ff5733" + "CCGT-95CCS": "#800000" + "8hr_PHS": "#069686" + "10hr_PHS": "#058a79" + "12hr_PHS": "#047d6c" + "8hr_PHS_discharger": "#069686" + "10hr_PHS_discharger": "#058a79" + "12hr_PHS_discharger": "#047d6c" + "8hr_PHS_charger": "#069686" + "10hr_PHS_charger": "#058a79" + "12hr_PHS_charger": "#047d6c" + + nice_names: + OCGT: "Open-Cycle Gas" + CCGT: "Combined-Cycle Gas" + offwind: "Fixed Bottom Offshore Wind" + offwind_floating: "Floating Offshore Wind" + onwind: "Onshore Wind" + solar: "Solar" + EGS: "EGS" + coal-99CCS: "Coal-99CCS" + coal-95CCS: "Coal-95CCS" + CCGT-95CCS: "Gas-95CCS" + SMR: "SMR" + PHS: "Pumped Hydro Storage" + hydro: "Reservoir & Dam" + battery: "Battery Storage" + H2: "Hydrogen Storage" + lines: "Transmission Lines" + ror: "Run of River" + Load: "Load Shed" + res-elec: "Residential Electrical" + res-heat: "Residential Heating" + res-cool: "Residential Cooling" + com-elec: "Commercial Electrical" + com-heat: "Commercial Heating" + com-cool: "Commercial Cooling" + ind-elec: "Industrial Electrical" + ind-heat: "Industrial Heating" + trn-elec: "Transportation Electrical" \ No newline at end of file diff --git a/workflow/config/config.tutorial.yaml b/workflow/config/config.tutorial.yaml new file mode 100644 index 00000000..bbd8d56a --- /dev/null +++ b/workflow/config/config.tutorial.yaml @@ -0,0 +1,287 @@ +# PyPSA-USA Default Configuration File + +run: + name: "Tutorial" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: false # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [texas] #"usa|texas|western|eastern" + clusters: [20] + opts: [REM-1000SEG] + ll: [v1.05] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: + - 2030 #(2018-2023, 2030, 2040, 2050) + +foresight: 'perfect' + + +# docs : +enable: + build_cutout: false + +snapshots: # Defines renewable weather year, and annual snapshot time-scope + start: "2019-01-01" + end: "2019-02-01" + inclusive: "left" + + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 + co2limit: 180.3e+3 + co2limit_enable: true + co2base: 180.3e+6 + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired + StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] + Store: [] + Link: [] + + demand: #EFS used for given planning_horizons year (only ref/mod implemented) + EFS_case: reference # reference, medium, high + EFS_speed: moderate # slow, moderate, rapid + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + max_extension: 1000.0e+3 + length_factor: 1.25 + interface_transmission_limits: true # Imposes ITLs over AC Lines + transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs + + +# docs : +links: + p_max_pu: 1.0 + p_nom_max: .inf + max_extension: 1000.0e+3 + +# docs : +load: + scaling_factor: 1.0 + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + ptc_modifier: + onwind: 18.2547 + geothermal: 18.2547 + biomass: 18.2547 + itc_modifier: + solar: 0.3 + offwind: 0.3 + offwind_floating: 0.3 + EGS: 0.3 + + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: false + aggregation_strategies: + generators: + committable: any + ramp_limit_up: max + ramp_limit_down: max + # Mean heat-rates, VOM, and fuel are not used in the model, only for post processing purposes + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + # California: 0.5 + + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: false + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 4 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 8 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 8 + cplex-default: + threads: 4 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "12:00:00" diff --git a/workflow/config/config.validation.yaml b/workflow/config/config.validation.yaml new file mode 100644 index 00000000..44eed3dd --- /dev/null +++ b/workflow/config/config.validation.yaml @@ -0,0 +1,284 @@ +# PyPSA-USA Validation Configuration File + +run: + name: "Validation_REEDS" # use this to keep track of runs with different settings + disable_progressbar: false # set to true to disable the progressbar + shared_resources: false # set to true to share the default resources across runs + shared_cutouts: true # set to true to share the default cutout(s) across runs + validation: true # set to true to run back-casting plots + +# docs : +scenario: + interconnect: [western] #"usa|texas|western|eastern" + clusters: [40] + opts: [Ep] + ll: [v1.0] + scope: "total" # "urban", "rural", or "total" + sector: "" # G + planning_horizons: + - 2019 #(2018-2023) + +foresight: 'perfect' + +# docs : +enable: + build_cutout: false + +snapshots: + start: "2019-01-01" + end: "2020-01-01" + inclusive: 'left' + +# docs : +electricity: + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network + renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network + voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" + co2limit: 1.4728e+9 # 0.8 * 1.841e+9 + co2limit_enable: false # For sector coupled studies + co2base: 226.86e+6 #base_from_2020 Locations of the 250 MMmt of CO2 emissions from the WECC 2021. + gaslimit: false # global gas usage limit of X MWh_th + gaslimit_enable: false # For sector coupled studies + retirement: economic # "economic" or "technical" + SAFE_reservemargin: 0.14 + regional_Co2_limits: 'config/policy_constraints/regional_Co2_limits.csv' + agg_p_nom_limits: 'config/policy_constraints/agg_p_nom_minmax.csv' + portfolio_standards: 'config/policy_constraints/portfolio_standards.csv' + SAFE_regional_reservemargins: 'config/policy_constraints/SAFE_regional_prm.csv' + transmission_interface_limits: 'config/policy_constraints/transmission_interface_limits.csv' + + operational_reserve: + activate: false + epsilon_load: 0.02 + epsilon_vres: 0.02 + contingency: 4000 + + max_hours: + battery: 6 + H2: 168 + + extendable_carriers: + Generator: [] + StorageUnit: [] + Store: [] + Link: [] + + demand: + profile: eia # efs, eia + scale: 1 # efs, aeo, or a number + disaggregation: pop # pop + scenario: + efs_case: reference # reference, medium, high + efs_speed: moderate # slow, moderate, rapid + aeo: reference + + autarky: + enable: false + by_country: false + +# docs : +conventional: + unit_commitment: false + dynamic_fuel_price: + pudl: true + wholesale: true + +# docs : +lines: + types: # All temporary values, need to be updated + 115.: "Al/St 240/40 2-bundle 220.0" + 138.: "Al/St 240/40 2-bundle 220.0" + 161.: "Al/St 240/40 2-bundle 220.0" + 230.: "Al/St 240/40 2-bundle 220.0" + 345.: "Al/St 240/40 4-bundle 380.0" + 500.: "Al/St 560/50 4-bundle 750.0" + 765.: "Al/St 560/50 4-bundle 750.0" + s_max_pu: 0.7 + s_nom_max: .inf + length_factor: 1.25 + interface_transmission_limits: true # Imposes ITLs over AC Lines + transport_model: false # If minimum nodes set, AC lines will be replaced with links according to ITLs + +# docs : +links: + p_max_pu: 0.7 + p_nom_max: .inf + +# docs : +load: + scaling_factor: 1.0 + +# docs : +costs: + social_discount_rate: 0.02 + version: v0.6.0 + rooftop_share: 0.0 + ng_fuel_year: 2019 # year of the natural gas price from CAISO [2019- 2023] + fill_values: + FOM: 0 + VOM: 0 + efficiency: 1 + fuel: 0 + investment: 0 + lifetime: 25 + "CO2 intensity": 0 + "discount rate": 0.07 + marginal_cost: + solar: 0.00 + onwind: 0.00 + offwind: 0.00 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + enable: false + co2: 0. + co2_monthly_prices: false + +# docs : +sector: + co2_sequestration_potential: 0 + natural_gas: + allow_imports_exports: true # false to be implemented + cyclic_storage: false + heating: + heat_pump_sink_T: 55. + demand: + profile: + residential: eulp # efs, eulp + commercial: eulp # efs, eulp + transport: efs # efs + industry: efs # efs + scale: + residential: aeo # efs, aeo + commercial: aeo # efs, aeo + transport: aeo # efs, aeo + industry: aeo # efs, aeo + disaggregation: + residential: pop # pop + commercial: pop # pop + transport: pop # pop + industry: pop # pop + scenarios: + aeo: reference + +# docs : +clustering: + simplify_network: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + algorithm: kmeans # choose from: [hac, kmeans] + feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc. + cluster_network: + algorithm: kmeans + feature: solar+onwind-time + aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] + exclude_carriers: [] + consider_efficiency_classes: False + aggregation_strategies: + generators: + committable: any + start_up_cost: 'capacity_weighted_average' + min_up_time: 'capacity_weighted_average' + min_down_time: 'capacity_weighted_average' + ramp_limit_up: max + ramp_limit_down: max + vom_cost: mean + fuel_cost: mean + heat_rate: mean + temporal: + resolution_elec: false + resolution_sector: false + +focus_weights: + +# docs : +solving: + #tmpdir: "path/to/tmp" + options: + load_shedding: true + clip_p_max_pu: 1.e-2 + noisy_costs: true + skip_iterations: true + rolling_horizon: false + seed: 123 + # options that go into the optimize function + track_iterations: false + min_iterations: 4 + max_iterations: 6 + transmission_losses: 2 + linearized_unit_commitment: true + horizon: 8760 + assign_all_duals: true + + + solver: + name: gurobi + options: gurobi-default + + solver_options: + highs-default: + # refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver + threads: 4 + solver: "ipm" + run_crossover: "off" + small_matrix_value: 1e-6 + large_matrix_value: 1e9 + primal_feasibility_tolerance: 1e-5 + dual_feasibility_tolerance: 1e-5 + ipm_optimality_tolerance: 1e-4 + parallel: "on" + random_seed: 123 + gurobi-default: + threads: 32 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-4 + OptimalityTol: 1.e-4 + FeasibilityTol: 1.e-3 + Seed: 123 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + gurobi-numeric-focus: + name: gurobi + NumericFocus: 3 # Favour numeric stability over speed + method: 2 # barrier + crossover: 0 # do not use crossover + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-4 + OptimalityTol: 1.e-4 + ObjScale: -0.5 + threads: 8 + Seed: 123 + gurobi-fallback: # Use gurobi defaults + name: gurobi + crossover: 0 + method: 2 # barrier + BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-5 + OptimalityTol: 1.e-5 + Seed: 123 + threads: 8 + cplex-default: + threads: 4 + lpmethod: 4 # barrier + solutiontype: 2 # non basic solution, ie no crossover + barrier.convergetol: 1.e-5 + feasopt.tolerance: 1.e-6 + cbc-default: {} # Used in CI + glpk-default: {} # Used in CI + + mem: 30000 #memory in MB; 20 GB enough for 50+B+I+H2; 100 GB for 181+B+I+H2 + walltime: "12:00:00" + + +# docs : +custom_files: + activate: false + files_path: '/Users/kamrantehranchi/Local_Documents/pypsa-usa/workflow/resources/CustomFiles/' + network_name: 'elec_s_40_ec.nc' \ No newline at end of file diff --git a/workflow/config/policy_constraints/.DS_Store b/workflow/config/policy_constraints/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 20 Aug 2024 23:51:02 +0000 Subject: [PATCH 17/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- workflow/config/config.common.yaml | 9 +- workflow/config/config.default.yaml | 16 ++-- workflow/config/config.egs.yaml | 16 ++-- workflow/config/config.mod_default.yaml | 16 ++-- workflow/config/config.plotting.yaml | 6 +- workflow/config/config.tutorial.yaml | 12 +-- workflow/config/config.validation.yaml | 16 ++-- .../policy_constraints/SAFE_regional_prm.csv | 4 +- .../policy_constraints/agg_p_nom_minmax.csv | 4 +- .../portfolio_standards.csv | 4 +- .../regional_Co2_limits.csv | 2 +- .../transmission_interface_limits.csv | 2 +- workflow/rules/build_electricity.smk | 3 +- workflow/rules/solve_myopic.smk | 1 - workflow/scripts/add_electricity.py | 86 ++++++++++++------- workflow/scripts/add_extra_components.py | 45 ++++++++-- workflow/scripts/plot_statistics.py | 2 +- workflow/scripts/simplify_network.py | 2 +- workflow/scripts/solve_network.py | 2 +- 19 files changed, 151 insertions(+), 97 deletions(-) diff --git a/workflow/config/config.common.yaml b/workflow/config/config.common.yaml index 3a665958..fb99ea27 100644 --- a/workflow/config/config.common.yaml +++ b/workflow/config/config.common.yaml @@ -1,4 +1,3 @@ - countries: [US] network_configuration: "pypsa-usa" # "pypsa-usa" or "ads2032" @@ -140,16 +139,16 @@ costs: EGS: 0.3 geothermal: 0.3 SMR: 0.3 - nuclear: 0.3 + nuclear: 0.3 hydro: 0.3 4hr_battery_storage: 0.3 6hr_battery_storage: 0.3 - 8hr_battery_storage: 0.3 + 8hr_battery_storage: 0.3 10hr_battery_storage: 0.3 8hr_PHS: 0.3 10hr_PHS: 0.3 12hr_PHS: 0.3 - ptc_modifier: + ptc_modifier: solar: 27.5 onwind: 27.5 - biomass: 27.5 \ No newline at end of file + biomass: 27.5 diff --git a/workflow/config/config.default.yaml b/workflow/config/config.default.yaml index 877e0dd6..5ea2d86e 100644 --- a/workflow/config/config.default.yaml +++ b/workflow/config/config.default.yaml @@ -18,7 +18,7 @@ scenario: planning_horizons: - 2030 #(2018-2023, 2030, 2040, 2050) -foresight: 'perfect' +foresight: 'perfect' # docs : @@ -36,7 +36,7 @@ electricity: conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, geothermal, biomass] # Choose the conventional plant types to include in network renewable_carriers: [onwind, offwind, offwind_floating, solar, hydro] # Choose the renewable plant types to include in network voltage_simplified: 230 #Voltage level to simplify network to in rule "simplify network" - co2limit: 1.4728e+9 + co2limit: 1.4728e+9 co2limit_enable: false co2base: 226.86e+6 gaslimit: false # global gas usage limit of X MWh_th @@ -64,11 +64,11 @@ electricity: Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] Store: [] - Link: [] + Link: [] - demand: + demand: profile: eia # efs, eia - scenario: + scenario: efs_case: reference # reference, medium, high efs_speed: moderate # slow, moderate, rapid aeo: reference @@ -80,7 +80,7 @@ electricity: # docs : conventional: unit_commitment: false - dynamic_fuel_price: + dynamic_fuel_price: pudl: true wholesale: true @@ -168,7 +168,7 @@ sector: commercial: aeo # efs, aeo transport: aeo # efs, aeo industry: aeo # efs, aeo - disaggregation: + disaggregation: residential: pop # pop commercial: pop # pop transport: pop # pop @@ -292,4 +292,4 @@ solving: custom_files: activate: false files_path: '' - network_name: '' \ No newline at end of file + network_name: '' diff --git a/workflow/config/config.egs.yaml b/workflow/config/config.egs.yaml index c4da598e..10a6f7e1 100644 --- a/workflow/config/config.egs.yaml +++ b/workflow/config/config.egs.yaml @@ -19,7 +19,7 @@ scenario: planning_horizons: [2030, 2040, 2050] # - 2030 #(2018-2023, 2030, 2040, 2050) -foresight: 'perfect' +foresight: 'perfect' # docs : @@ -65,11 +65,11 @@ electricity: Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR, nuclear, EGS] #offwind, offwind_floating, maybe include CCGT-CCS StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] Store: [] - Link: [] + Link: [] - demand: + demand: profile: efs # efs, eia - scenario: + scenario: efs_case: reference # reference, medium, high efs_speed: moderate # slow, moderate, rapid aeo: reference @@ -81,7 +81,7 @@ electricity: # docs : conventional: unit_commitment: false - dynamic_fuel_price: + dynamic_fuel_price: pudl: true wholesale: true @@ -100,7 +100,7 @@ lines: max_extension: 1000.0e+3 length_factor: 1.25 interface_transmission_limits: true - transport_model : true + transport_model: true # docs : links: @@ -158,7 +158,7 @@ sector: commercial: aeo # efs, aeo transport: aeo # efs, aeo industry: aeo # efs, aeo - disaggregation: + disaggregation: residential: pop # pop commercial: pop # pop transport: pop # pop @@ -285,4 +285,4 @@ solving: custom_files: activate: false files_path: '' - network_name: '' \ No newline at end of file + network_name: '' diff --git a/workflow/config/config.mod_default.yaml b/workflow/config/config.mod_default.yaml index 05617bb9..b55aac7d 100644 --- a/workflow/config/config.mod_default.yaml +++ b/workflow/config/config.mod_default.yaml @@ -19,7 +19,7 @@ scenario: planning_horizons: [2030, 2040, 2050] # - 2030 #(2018-2023, 2030, 2040, 2050) -foresight: 'perfect' +foresight: 'perfect' # docs : @@ -65,11 +65,11 @@ electricity: Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal, CCGT-95CCS, coal-99CCS, coal-95CCS, SMR, nuclear] #offwind, offwind_floating, maybe include CCGT-CCS StorageUnit: [4hr_battery_storage, 6hr_battery_storage, 8hr_battery_storage, 10hr_battery_storage, 8hr_PHS, 10hr_PHS, 12hr_PHS] # [Xhr-battery-storage (2-10 hours)] Store: [] - Link: [] + Link: [] - demand: + demand: profile: efs # efs, eia - scenario: + scenario: efs_case: reference # reference, medium, high efs_speed: moderate # slow, moderate, rapid aeo: reference @@ -81,7 +81,7 @@ electricity: # docs : conventional: unit_commitment: false - dynamic_fuel_price: + dynamic_fuel_price: pudl: true wholesale: true @@ -100,7 +100,7 @@ lines: max_extension: 1000.0e+3 length_factor: 1.25 interface_transmission_limits: true - transport_model : true + transport_model: true # docs : links: @@ -158,7 +158,7 @@ sector: commercial: aeo # efs, aeo transport: aeo # efs, aeo industry: aeo # efs, aeo - disaggregation: + disaggregation: residential: pop # pop commercial: pop # pop transport: pop # pop @@ -285,4 +285,4 @@ solving: custom_files: activate: false files_path: '' - network_name: '' \ No newline at end of file + network_name: '' diff --git a/workflow/config/config.plotting.yaml b/workflow/config/config.plotting.yaml index 1332b9a2..e203c816 100644 --- a/workflow/config/config.plotting.yaml +++ b/workflow/config/config.plotting.yaml @@ -84,13 +84,13 @@ plotting: "CCGT-95CCS": "#800000" "8hr_PHS": "#069686" "10hr_PHS": "#058a79" - "12hr_PHS": "#047d6c" + "12hr_PHS": "#047d6c" "8hr_PHS_discharger": "#069686" "10hr_PHS_discharger": "#058a79" "12hr_PHS_discharger": "#047d6c" "8hr_PHS_charger": "#069686" "10hr_PHS_charger": "#058a79" - "12hr_PHS_charger": "#047d6c" + "12hr_PHS_charger": "#047d6c" nice_names: OCGT: "Open-Cycle Gas" @@ -119,4 +119,4 @@ plotting: com-cool: "Commercial Cooling" ind-elec: "Industrial Electrical" ind-heat: "Industrial Heating" - trn-elec: "Transportation Electrical" \ No newline at end of file + trn-elec: "Transportation Electrical" diff --git a/workflow/config/config.tutorial.yaml b/workflow/config/config.tutorial.yaml index bbd8d56a..ddb836e8 100644 --- a/workflow/config/config.tutorial.yaml +++ b/workflow/config/config.tutorial.yaml @@ -18,7 +18,7 @@ scenario: planning_horizons: - 2030 #(2018-2023, 2030, 2040, 2050) -foresight: 'perfect' +foresight: 'perfect' # docs : @@ -63,7 +63,7 @@ electricity: Generator: [solar, onwind, offwind, offwind_floating, OCGT, CCGT, coal] # Select Generator types allowed to be built/retired StorageUnit: [4hr_battery_storage] # [Xhr-battery-storage (2-10 hours), Xhr-PHS (8,10,12 hrs)] Store: [] - Link: [] + Link: [] demand: #EFS used for given planning_horizons year (only ref/mod implemented) EFS_case: reference # reference, medium, high @@ -76,7 +76,7 @@ electricity: # docs : conventional: unit_commitment: false - dynamic_fuel_price: + dynamic_fuel_price: pudl: true wholesale: true @@ -109,7 +109,7 @@ load: scaling_factor: 1.0 # docs : -costs: +costs: social_discount_rate: 0.02 version: v0.6.0 rooftop_share: 0.0 @@ -167,7 +167,7 @@ sector: commercial: aeo # efs, aeo transport: aeo # efs, aeo industry: aeo # efs, aeo - disaggregation: + disaggregation: residential: pop # pop commercial: pop # pop transport: pop # pop @@ -195,7 +195,7 @@ clustering: # Mean heat-rates, VOM, and fuel are not used in the model, only for post processing purposes vom_cost: mean fuel_cost: mean - heat_rate: mean + heat_rate: mean temporal: resolution_elec: false resolution_sector: false diff --git a/workflow/config/config.validation.yaml b/workflow/config/config.validation.yaml index 44eed3dd..0cd4e26f 100644 --- a/workflow/config/config.validation.yaml +++ b/workflow/config/config.validation.yaml @@ -18,7 +18,7 @@ scenario: planning_horizons: - 2019 #(2018-2023) -foresight: 'perfect' +foresight: 'perfect' # docs : enable: @@ -63,11 +63,11 @@ electricity: Store: [] Link: [] - demand: + demand: profile: eia # efs, eia - scale: 1 # efs, aeo, or a number + scale: 1 # efs, aeo, or a number disaggregation: pop # pop - scenario: + scenario: efs_case: reference # reference, medium, high efs_speed: moderate # slow, moderate, rapid aeo: reference @@ -79,7 +79,7 @@ electricity: # docs : conventional: unit_commitment: false - dynamic_fuel_price: + dynamic_fuel_price: pudl: true wholesale: true @@ -157,7 +157,7 @@ sector: commercial: aeo # efs, aeo transport: aeo # efs, aeo industry: aeo # efs, aeo - disaggregation: + disaggregation: residential: pop # pop commercial: pop # pop transport: pop # pop @@ -176,7 +176,7 @@ clustering: feature: solar+onwind-time aggregation_zones: 'reeds_zone' # [balancing_area, state, reeds_zone] exclude_carriers: [] - consider_efficiency_classes: False + consider_efficiency_classes: false aggregation_strategies: generators: committable: any @@ -281,4 +281,4 @@ solving: custom_files: activate: false files_path: '/Users/kamrantehranchi/Local_Documents/pypsa-usa/workflow/resources/CustomFiles/' - network_name: 'elec_s_40_ec.nc' \ No newline at end of file + network_name: 'elec_s_40_ec.nc' diff --git a/workflow/config/policy_constraints/SAFE_regional_prm.csv b/workflow/config/policy_constraints/SAFE_regional_prm.csv index 5b58bcca..e5176198 100644 --- a/workflow/config/policy_constraints/SAFE_regional_prm.csv +++ b/workflow/config/policy_constraints/SAFE_regional_prm.csv @@ -1,2 +1,2 @@ -region_type,planning_horizon,region,prm -state,2030,fake_state,0.16 \ No newline at end of file +region_type,planning_horizon,region,prm +state,2030,fake_state,0.16 diff --git a/workflow/config/policy_constraints/agg_p_nom_minmax.csv b/workflow/config/policy_constraints/agg_p_nom_minmax.csv index add881f3..bef8e5c1 100644 --- a/workflow/config/policy_constraints/agg_p_nom_minmax.csv +++ b/workflow/config/policy_constraints/agg_p_nom_minmax.csv @@ -1,2 +1,2 @@ -planning_horizon,region,carrier,min,max -2030,p63,solar,0, \ No newline at end of file +planning_horizon,region,carrier,min,max +2030,p63,solar,0, diff --git a/workflow/config/policy_constraints/portfolio_standards.csv b/workflow/config/policy_constraints/portfolio_standards.csv index 6984fdd6..cf6e1224 100644 --- a/workflow/config/policy_constraints/portfolio_standards.csv +++ b/workflow/config/policy_constraints/portfolio_standards.csv @@ -1,2 +1,2 @@ -planning_horizon,region,carrier,pct,notes -2030,custom,"onwind, solar, offwind_floating, geothermal, offwind",0.6,example_entry \ No newline at end of file +planning_horizon,region,carrier,pct,notes +2030,custom,"onwind, solar, offwind_floating, geothermal, offwind",0.6,example_entry diff --git a/workflow/config/policy_constraints/regional_Co2_limits.csv b/workflow/config/policy_constraints/regional_Co2_limits.csv index 01b3686d..f4f9e841 100644 --- a/workflow/config/policy_constraints/regional_Co2_limits.csv +++ b/workflow/config/policy_constraints/regional_Co2_limits.csv @@ -51,4 +51,4 @@ RGGI,"CT, DE, MA, MD, ME, NH, NJ, NY, RI, VA, VT",2049,78811768,0,reeds data RGGI,"CT, DE, MA, MD, ME, NH, NJ, NY, RI, VA, VT",2050,78811768,0,reeds data all_2030,"all",2030,2883000000,0, based on reeds numbers of percentage reductions all_2040,"all",2040,0,0, based on reeds numbers of percentage reductions -all_2050,"all",2050,0,0, based on reeds numbers of percentage reductions \ No newline at end of file +all_2050,"all",2050,0,0, based on reeds numbers of percentage reductions diff --git a/workflow/config/policy_constraints/transmission_interface_limits.csv b/workflow/config/policy_constraints/transmission_interface_limits.csv index 5ffe70ce..5e800e35 100644 --- a/workflow/config/policy_constraints/transmission_interface_limits.csv +++ b/workflow/config/policy_constraints/transmission_interface_limits.csv @@ -1,4 +1,4 @@ interface,region_1,region_2,flow_12,flow_21,Notes CA_NW,"p9, p10, p11","p2, p5, p6, p7, p8",3591.96,9269.23,RESOLVE CA_SW,"p9, p10, p11","p12, p13, p30, p28, p27, p25",10901,10463,RESOLVE -CAISO_Imports,"p9, p10, p11","p2, p5, p6, p7, p8, p12, p13, p30, p28, p27, p25",9728,10208,RESOLVE \ No newline at end of file +CAISO_Imports,"p9, p10, p11","p2, p5, p6, p7, p8, p12, p13, p30, p28, p27, p25",9728,10208,RESOLVE diff --git a/workflow/rules/build_electricity.smk b/workflow/rules/build_electricity.smk index 171ddb51..47c4e6c4 100644 --- a/workflow/rules/build_electricity.smk +++ b/workflow/rules/build_electricity.smk @@ -550,8 +550,7 @@ rule cluster_network: rule add_extra_components: input: **{ - f"phs_shp_{hour}": - f"repo_data/psh/40-100-dam-height-{hour}hr-no-croplands-no-ephemeral-no-highways.gpkg" + f"phs_shp_{hour}": f"repo_data/psh/40-100-dam-height-{hour}hr-no-croplands-no-ephemeral-no-highways.gpkg" for phs_tech in config["electricity"]["extendable_carriers"]["StorageUnit"] if "PHS" in phs_tech for hour in phs_tech.split("hr_") diff --git a/workflow/rules/solve_myopic.smk b/workflow/rules/solve_myopic.smk index 15c96c1e..b314bfad 100644 --- a/workflow/rules/solve_myopic.smk +++ b/workflow/rules/solve_myopic.smk @@ -91,4 +91,3 @@ rule solve_sector_network_myopic: "../envs/environment.yaml" script: "../scripts/solve_network.py" - diff --git a/workflow/scripts/add_electricity.py b/workflow/scripts/add_electricity.py index 1b8d79d9..3b332778 100755 --- a/workflow/scripts/add_electricity.py +++ b/workflow/scripts/add_electricity.py @@ -43,6 +43,7 @@ from typing import Any, Dict, List, Union import constants as const +import dill as pickle import geopandas as gpd import numpy as np import pandas as pd @@ -60,7 +61,6 @@ from shapely.geometry import Point from shapely.prepared import prep from sklearn.neighbors import BallTree -import dill as pickle idx = pd.IndexSlice @@ -814,6 +814,7 @@ def attach_wind_and_solar( p_max_pu=bus_profiles, ) + def attach_egs( n: pypsa.Network, costs: pd.DataFrame, @@ -832,10 +833,16 @@ def attach_egs( add_missing_carriers(n, carriers) - lifetime = 25 # Following EGS supply curves by Aljubran et al. (2024) - discount_rate = load_costs(snakemake.input.tech_costs, snakemake.params.costs, snakemake.params.max_hours).loc[car, "discount rate"] + lifetime = 25 # Following EGS supply curves by Aljubran et al. (2024) + discount_rate = load_costs( + snakemake.input.tech_costs, snakemake.params.costs, snakemake.params.max_hours + ).loc[car, "discount rate"] - with xr.open_dataset(getattr(input_profiles, "specs_EGS")) as ds_specs, xr.open_dataset(getattr(input_profiles, "profile_EGS")) as ds_profile: + with xr.open_dataset( + getattr(input_profiles, "specs_EGS") + ) as ds_specs, xr.open_dataset( + getattr(input_profiles, "profile_EGS") + ) as ds_profile: bus2sub = ( pd.read_csv(input_profiles.bus2sub, dtype=str) @@ -844,44 +851,64 @@ def attach_egs( ) # IGNORE: Remove dropna(). Rather, apply dropna when creating the original dataset - df_specs = pd.merge(ds_specs.to_dataframe().reset_index().dropna(), bus2sub, on="sub_id", how="left") + df_specs = pd.merge( + ds_specs.to_dataframe().reset_index().dropna(), + bus2sub, + on="sub_id", + how="left", + ) df_specs["bus_id"] = df_specs["bus_id"].astype(str) # bus_id must be in index for pypsa to read it df_specs.set_index("bus_id", inplace=True) # columns must be renamed to refer to the right quantities for pypsa to read it correctly - df_specs = df_specs.rename(columns={ - "capex_usd_kw": "capital_cost", - #"advanced_capex_usd_kw": "capital_cost", - "avail_capacity_mw": "p_nom_max", - "fixed_om": "fixed_om"}) + df_specs = df_specs.rename( + columns={ + "capex_usd_kw": "capital_cost", + # "advanced_capex_usd_kw": "capital_cost", + "avail_capacity_mw": "p_nom_max", + "fixed_om": "fixed_om", + }, + ) # TODO: come up with proper values for these params - df_specs["capital_cost"] = 1000 * (df_specs["capital_cost"] * calculate_annuity(lifetime, discount_rate) + df_specs["fixed_om"])#convert and annualize USD/kW to USD/MW-year + df_specs["capital_cost"] = 1000 * ( + df_specs["capital_cost"] * calculate_annuity(lifetime, discount_rate) + + df_specs["fixed_om"] + ) # convert and annualize USD/kW to USD/MW-year df_specs["efficiency"] = 1.0 # TODO: review what qualities need to be included. Currently limited for speedup. - qualities = [1]#df_specs.Quality.unique() + qualities = [1] # df_specs.Quality.unique() for q in qualities: - suffix = " " + car# + f" Q{q}" + suffix = " " + car # + f" Q{q}" df_q = df_specs[df_specs["Quality"] == q] bus_list = df_q.index.values - capital_cost = df_q["capital_cost"] + capital_cost = df_q["capital_cost"] p_nom_max_bus = df_q["p_nom_max"] - efficiency = df_q["efficiency"] # for now. + efficiency = df_q["efficiency"] # for now. # IGNORE: Remove dropna(). Rather, apply dropna when creating the original dataset - df_q_profile = pd.merge(ds_profile.sel(Quality=q).to_dataframe().dropna().reset_index(), - bus2sub, - on="sub_id", how="left") - bus_profiles = pd.pivot_table(df_q_profile, columns="bus_id", - index=["year", "Date"], values="capacity_factor") + df_q_profile = pd.merge( + ds_profile.sel(Quality=q).to_dataframe().dropna().reset_index(), + bus2sub, + on="sub_id", + how="left", + ) + bus_profiles = pd.pivot_table( + df_q_profile, + columns="bus_id", + index=["year", "Date"], + values="capacity_factor", + ) - logger.info(f"Adding EGS (Resource Quality-{q}) capacity-factor profiles to the network.") + logger.info( + f"Adding EGS (Resource Quality-{q}) capacity-factor profiles to the network." + ) n.madd( "Generator", @@ -897,6 +924,7 @@ def attach_egs( p_max_pu=bus_profiles, ) + def attach_battery_storage( n: pypsa.Network, plants: pd.DataFrame, @@ -1207,14 +1235,14 @@ def main(snakemake): plants = match_plant_to_bus(n, plants) attach_egs( - n, - costs, - snakemake.input, - renewable_carriers, - extendable_carriers, - params.length_factor, - ) - + n, + costs, + snakemake.input, + renewable_carriers, + extendable_carriers, + params.length_factor, + ) + attach_conventional_generators( n, costs, diff --git a/workflow/scripts/add_extra_components.py b/workflow/scripts/add_extra_components.py index 053531ed..05f3c7fc 100644 --- a/workflow/scripts/add_extra_components.py +++ b/workflow/scripts/add_extra_components.py @@ -476,6 +476,7 @@ def attach_multihorizon_generators( ) n.generators_t["p_max_pu"] = n.generators_t["p_max_pu"].join(p_max_pu_t) + def attach_multihorizon_egs( n: pypsa.Network, costs: pd.DataFrame, @@ -485,6 +486,7 @@ def attach_multihorizon_egs( ): """ Adds multiple investment options for EGS. + Arguments: n: pypsa.Network, costs: pd.DataFrame, @@ -497,10 +499,12 @@ def attach_multihorizon_egs( if gens.empty or len(n.investment_periods) == 1: return - lifetime = 25 # Following EGS supply curves by Aljubran et al. (2024) + lifetime = 25 # Following EGS supply curves by Aljubran et al. (2024) base_year = n.investment_periods[0] base_capex = costs_dict[base_year].loc["EGS", "investment"] - learning_ratio = costs.loc["EGS", "investment"]/costs_dict[base_year].loc["EGS", "investment"] + learning_ratio = ( + costs.loc["EGS", "investment"] / costs_dict[base_year].loc["EGS", "investment"] + ) capital_cost = learning_ratio * gens["capital_cost"] n.madd( @@ -547,8 +551,21 @@ def attach_multihorizon_egs( # shift over time to capture decline investment_year_idx = np.where(n.investment_periods == investment_year)[0][0] - cars = list(n.generators_t["p_max_pu"].filter(like="EGS").filter(like=str(investment_year)).columns) - n.generators_t["p_max_pu"].loc[n.investment_periods[investment_year_idx:], cars] = n.generators_t["p_max_pu"].loc[n.investment_periods[:len(n.investment_periods)-investment_year_idx], cars].values + cars = list( + n.generators_t["p_max_pu"] + .filter(like="EGS") + .filter(like=str(investment_year)) + .columns + ) + n.generators_t["p_max_pu"].loc[n.investment_periods[investment_year_idx:], cars] = ( + n.generators_t["p_max_pu"] + .loc[ + n.investment_periods[: len(n.investment_periods) - investment_year_idx], + cars, + ] + .values + ) + def attach_newCarrier_generators(n, costs, carriers, investment_year): """ @@ -588,9 +605,11 @@ def attach_newCarrier_generators(n, costs, carriers, investment_year): lifetime=costs.at[carrier, "lifetime"], ) + def apply_itc(n, itc_modifier): """ Applies investment tax credit to all extendable components in the network. + Arguments: n: pypsa.Network, itc_modifier: dict, @@ -600,15 +619,17 @@ def apply_itc(n, itc_modifier): for carrier in itc_modifier.keys(): # apply to generators carrier_mask = n.generators["carrier"] == carrier - n.generators.loc[carrier_mask, "capital_cost"] *= (1 - itc_modifier[carrier]) + n.generators.loc[carrier_mask, "capital_cost"] *= 1 - itc_modifier[carrier] # apply to storage units carrier_mask = n.storage_units["carrier"] == carrier - n.storage_units.loc[carrier_mask, "capital_cost"] *= (1 - itc_modifier[carrier]) + n.storage_units.loc[carrier_mask, "capital_cost"] *= 1 - itc_modifier[carrier] + def apply_ptc(n, ptc_modifier): """ Applies production tax credit to all extendable components in the network. + Arguments: n: pypsa.Network, ptc_modifier: dict, @@ -674,7 +695,15 @@ def apply_ptc(n, ptc_modifier): if any("PHS" in s for s in elec_config["extendable_carriers"]["StorageUnit"]): attach_phs_storageunits(n, elec_config) - gens = gens[gens["carrier"].isin([car for car in elec_config["extendable_carriers"]["Generator"] if "EGS" not in car])] + gens = gens[ + gens["carrier"].isin( + [ + car + for car in elec_config["extendable_carriers"]["Generator"] + if "EGS" not in car + ] + ) + ] egs_gens = n.generators[n.generators["p_nom_extendable"] == True] egs_gens = egs_gens.loc[egs_gens["carrier"].str.contains("EGS")] @@ -695,7 +724,7 @@ def apply_ptc(n, ptc_modifier): apply_itc(n, snakemake.config["costs"]["itc_modifier"]) apply_ptc(n, snakemake.config["costs"]["ptc_modifier"]) - + add_nice_carrier_names(n, snakemake.config) n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards))) diff --git a/workflow/scripts/plot_statistics.py b/workflow/scripts/plot_statistics.py index ca7a12a7..6003e687 100644 --- a/workflow/scripts/plot_statistics.py +++ b/workflow/scripts/plot_statistics.py @@ -121,7 +121,7 @@ def stacked_bar_horizons( y_positions = np.arange(len(stats)) # One position for each scenario for j, (scenario, df) in enumerate(stats.items()): bottoms = np.zeros( - len(df.columns) + len(df.columns), ) # Initialize the bottom positions for stacking # Stack the technologies for each scenario for i, technology in enumerate(df.index.unique()): diff --git a/workflow/scripts/simplify_network.py b/workflow/scripts/simplify_network.py index 85ae19b9..cec0ad57 100644 --- a/workflow/scripts/simplify_network.py +++ b/workflow/scripts/simplify_network.py @@ -8,6 +8,7 @@ import os from functools import reduce +import dill as pickle import geopandas as gpd import numpy as np import pandas as pd @@ -20,7 +21,6 @@ ) from cluster_network import cluster_regions, clustering_for_n_clusters from pypsa.clustering.spatial import get_clustering_from_busmap -import dill as pickle logger = logging.getLogger(__name__) diff --git a/workflow/scripts/solve_network.py b/workflow/scripts/solve_network.py index 57612a36..0d883b7b 100644 --- a/workflow/scripts/solve_network.py +++ b/workflow/scripts/solve_network.py @@ -77,7 +77,7 @@ def check_p_min_p_max(p_nom_max): f"summed p_min_pu values at node larger than technical potential {check[check].index}", ) - grouper = [n.generators.carrier, n.generators.bus]#, n.generators.build_year] + grouper = [n.generators.carrier, n.generators.bus] # , n.generators.build_year] ext_i = n.generators.p_nom_extendable & ~n.generators.index.str.contains("existing") # get technical limit per node and investment period p_nom_max = n.generators[ext_i].groupby(grouper).min().p_nom_max