Skip to content
New issue

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

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

Already on GitHub? # 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