Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inclusion of Enhanced Geothermal Systems (EGS) #490

Merged
merged 10 commits into from
Dec 19, 2024
2 changes: 2 additions & 0 deletions workflow/repo_data/config/config.common.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
foresight: 'perfect'
# docs :
renewable:
EGS:
dispatch: baseload # baseload or flexible
onwind:
cutout: era5
resource:
Expand Down
5 changes: 3 additions & 2 deletions workflow/repo_data/config/config.plotting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ plotting:
"12hr_PHS_discharger": "#047d6c"
"8hr_PHS_charger": "#069686"
"10hr_PHS_charger": "#058a79"
"12hr_PHS_charger": "#047d6c"
"12hr_PHS_charger": "#047d6c"
"EGS": "#d18372"
"hydrogen_ct": "#ea048a"


# sector studies only

res-elec: "#f9d002"
Expand Down Expand Up @@ -259,6 +259,7 @@ plotting:
lines: "Transmission Lines"
ror: "Run of River"
Load: "Load Shed"
EGS: "Enhanced Geothermal"
hydrogen_ct: "Hydrogen Combustion Turbine"

# sector studies only
Expand Down
82 changes: 82 additions & 0 deletions workflow/repo_data/costs/egs_costs.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
pypsa-name,parameter,value,investment_horizon
EGS,annualized_capex_fom,510917.007,2040
EGS,annualized_capex_per_mw,398586.811,2040
EGS,annualized_capex_per_mw_km,,2040
EGS,annualized_connection_capex_per_mw_km,4.113,2040
EGS,capacity_factor,0.9,2040
EGS,capex_construction_finance_factor,1897.835,2040
EGS,capex_grid_connection_per_kw,100,2040
EGS,capex_grid_connection_per_kw_km,62.15,2040
EGS,capex_overnight_additional_per_kw,,2040
EGS,capex_overnight_per_kw,4024.807,2040
EGS,capex_per_kw,6022.642,2040
EGS,capex_per_mw_km,,2040
EGS,co2_emissions,,2040
EGS,cost_recovery_period_years,25,2040
EGS,efficiency,0.384,2040
EGS,fuel_cost,,2040
EGS,fuel_cost_per_mwh,,2040
EGS,fuel_cost_real_per_mwhth,,2040
EGS,heat_rate_mmbtu_per_mwh,8.881,2040
EGS,heat_rate_penalty,,2040
EGS,levelized_cost_of_energy_per_mwh,49.754,2040
EGS,lifetime,25,2040
EGS,marginal_cost,,2040
EGS,net_output_penalty,,2040
EGS,opex_fixed_per_kw,112.33,2040
EGS,opex_variable_per_mwh,,2040
EGS,wacc_real,0.052,2040
EGS,annualized_capex_fom,491894.777,2050
EGS,annualized_capex_per_mw,379564.581,2050
EGS,annualized_capex_per_mw_km,,2050
EGS,annualized_connection_capex_per_mw_km,4.113,2050
EGS,capacity_factor,0.9,2050
EGS,capex_construction_finance_factor,1807.3,2050
EGS,capex_grid_connection_per_kw,100,2050
EGS,capex_grid_connection_per_kw_km,62.15,2050
EGS,capex_overnight_additional_per_kw,,2050
EGS,capex_overnight_per_kw,3828.035,2050
EGS,capex_per_kw,5735.334,2050
EGS,capex_per_mw_km,,2050
EGS,co2_emissions,,2050
EGS,cost_recovery_period_years,25,2050
EGS,efficiency,0.384,2050
EGS,fuel_cost,,2050
EGS,fuel_cost_per_mwh,,2050
EGS,fuel_cost_real_per_mwhth,,2050
EGS,heat_rate_mmbtu_per_mwh,8.881,2050
EGS,heat_rate_penalty,,2050
EGS,levelized_cost_of_energy_per_mwh,48.06,2050
EGS,lifetime,25,2050
EGS,marginal_cost,,2050
EGS,net_output_penalty,,2050
EGS,opex_fixed_per_kw,112.33,2050
EGS,opex_variable_per_mwh,,2050
EGS,wacc_real,0.052,2050
EGS,annualized_capex_fom,544721.506,2030
EGS,annualized_capex_per_mw,429012.29,2030
EGS,annualized_capex_per_mw_km,,2030
EGS,annualized_connection_capex_per_mw_km,4.113,2030
EGS,capacity_factor,0.9,2030
EGS,capex_construction_finance_factor,2071.03,2030
EGS,capex_grid_connection_per_kw,100,2030
EGS,capex_grid_connection_per_kw_km,62.15,2030
EGS,capex_overnight_additional_per_kw,,2030
EGS,capex_overnight_per_kw,4311.228,2030
EGS,capex_per_kw,6482.259,2030
EGS,capex_per_mw_km,,2030
EGS,co2_emissions,,2030
EGS,cost_recovery_period_years,25,2030
EGS,efficiency,0.384,2030
EGS,fuel_cost,,2030
EGS,fuel_cost_per_mwh,,2030
EGS,fuel_cost_real_per_mwhth,,2030
EGS,heat_rate_mmbtu_per_mwh,8.881,2030
EGS,heat_rate_penalty,,2030
EGS,levelized_cost_of_energy_per_mwh,52.893,2030
EGS,lifetime,25,2030
EGS,marginal_cost,,2030
EGS,net_output_penalty,,2030
EGS,opex_fixed_per_kw,115.709,2030
EGS,opex_variable_per_mwh,,2030
EGS,wacc_real,0.052,2030
22 changes: 17 additions & 5 deletions workflow/rules/build_electricity.smk
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ rule build_shapes:
"logs/build_shapes/{interconnect}.log",
threads: 1
resources:
mem_mb=2000,
mem_mb=5000,
script:
"../scripts/build_shapes.py"

Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -99,6 +99,7 @@ rule build_cost_data:
efs_tech_costs="repo_data/costs/EFS_Technology_Data.xlsx",
efs_icev_costs="repo_data/costs/efs_icev_costs.csv",
eia_tech_costs="repo_data/costs/eia_tech_costs.csv",
egs_costs="repo_data/costs/egs_costs.csv",
additional_costs="repo_data/costs/additional_costs.csv",
output:
tech_costs=RESOURCES + "costs/costs_{year}.csv",
Expand All @@ -107,7 +108,7 @@ rule build_cost_data:
LOGS + "costs_{year}.log",
threads: 1
resources:
mem_mb=1000,
mem_mb=5000,
script:
"../scripts/build_cost_data.py"

Expand All @@ -134,7 +135,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"

Expand Down Expand Up @@ -208,10 +209,11 @@ rule build_renewable_profiles:
benchmark:
BENCHMARKS + "{interconnect}/build_renewable_profiles_{technology}"
threads: ATLITE_NPROCESSES
retries: 3
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"

Expand Down Expand Up @@ -607,6 +609,16 @@ 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=(
DATA + "EGS/{interconnect}/specs_EGS.nc"
if "EGS" in config["electricity"]["extendable_carriers"]["Generator"]
else []
),
profile_egs=(
DATA + "EGS/{interconnect}/profile_EGS.nc"
if "EGS" in config["electricity"]["extendable_carriers"]["Generator"]
else []
),
output:
RESOURCES + "{interconnect}/elec_base_network_l_pp.pkl",
log:
Expand Down
4 changes: 2 additions & 2 deletions workflow/rules/build_sector.smk
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ rule build_simplified_population_layouts:
output:
clustered_pop_layout=RESOURCES + "{interconnect}/pop_layout_elec_s.csv",
resources:
mem_mb=10000,
mem_mb=50000,
log:
LOGS + "{interconnect}/build_simplified_population_layouts",
benchmark:
Expand Down Expand Up @@ -175,7 +175,7 @@ rule build_clustered_population_layouts:
LOGS
+ "{interconnect}/build_clustered_population_layouts_{simpl}_{clusters}.log",
resources:
mem_mb=10000,
mem_mb=50000,
benchmark:
(
BENCHMARKS
Expand Down
16 changes: 8 additions & 8 deletions workflow/rules/common.smk
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def solver_threads(w):


def memory(w):
factor = 4.0
factor = 10.0
for o in w.opts.split("-"):
m = re.match(r"^(\d+)h$", o, re.IGNORECASE)
if m is not None:
Expand Down Expand Up @@ -119,25 +119,25 @@ 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":
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)


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":
return int(mem * 3)
elif w.interconnect == "western":
return int(mem)
return int(mem * 2)
elif w.interconnect == "texas":
return int(mem * 0.5)

Expand All @@ -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)

Expand All @@ -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)

Expand Down
23 changes: 22 additions & 1 deletion workflow/rules/retrieve.smk
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ rule retrieve_zenodo_databundles:
DATA + "breakthrough_network/base_grid/{file}", file=breakthrough_datafiles
),
expand(DATA + "{file}", file=pypsa_usa_datafiles),
resources:
mem_mb=5000,
log:
"logs/retrieve/retrieve_databundles.log",
script:
Expand All @@ -65,6 +67,8 @@ rule retrieve_nrel_efs_data:
efs_databundle,
output:
DATA + "nrel_efs/EFSLoadProfile_{efs_case}_{efs_speed}.csv",
resources:
mem_mb=5000,
log:
"logs/retrieve/retrieve_efs_{efs_case}_{efs_speed}.log",
script:
Expand Down Expand Up @@ -237,6 +241,23 @@ rule retrieve_pudl:
log:
LOGS + "retrieve_pudl.log",
resources:
mem_mb=1000,
mem_mb=5000,
script:
"../scripts/retrieve_pudl.py"


if "EGS" in config["electricity"]["extendable_carriers"]["Generator"]:

rule retrieve_egs:
params:
dispatch=config["renewable"]["EGS"]["dispatch"],
subdir=DATA + "EGS/{interconnect}",
output:
DATA + "EGS/{interconnect}/specs_EGS.nc",
DATA + "EGS/{interconnect}/profile_EGS.nc",
resources:
mem_mb=5000,
log:
LOGS + "retrieve_EGS_{interconnect}.log",
script:
"../scripts/retrieve_egs.py"
2 changes: 1 addition & 1 deletion workflow/run_slurm.sh
Original file line number Diff line number Diff line change
@@ -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 10 --latency-wait 60 --configfile config/base_paper/config.validation.yaml --rerun-incomplete -R build_powerplants
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 10 --latency-wait 60 --configfile config/config.egs_study.yaml
2 changes: 1 addition & 1 deletion workflow/scripts/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def calculate_annuity(n, r):

def load_costs(tech_costs: str) -> pd.DataFrame:
df = pd.read_csv(tech_costs)
return df.pivot(index="technology", columns="parameter", values="value").fillna(0)
return df.pivot(index="pypsa-name", columns="parameter", values="value").fillna(0)


def load_network_for_plots(fn, tech_costs, config, combine_hydro_ps=True):
Expand Down
Loading