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

Syncing GreenSteel and GreenHEART features #322

Merged
merged 24 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
016df73
limit pyyaml-include version
kbrunik Apr 1, 2024
b1530dd
autoformatter
kbrunik Apr 1, 2024
072586a
merge PR changes
kbrunik Apr 2, 2024
39cb5db
ran black autoformatter
kbrunik Apr 2, 2024
4a21e2f
reformat examples
kbrunik Apr 2, 2024
0231cf0
Merge remote-tracking branch 'upstream/greensteel-eco-sync' into gree…
kbrunik Apr 18, 2024
bd324b4
update variable name
kbrunik Apr 18, 2024
ee7aae2
GreenSteel tests
kbrunik Apr 19, 2024
c92ed97
Merge remote-tracking branch 'upstream/greensteel-eco-sync' into gree…
kbrunik May 1, 2024
9e25783
Merge remote-tracking branch 'jared/uniform-output' into greenheart-l…
kbrunik May 1, 2024
14f1c38
fix ammonia lcoh value
kbrunik May 21, 2024
d50f28c
Merge remote-tracking branch 'upstream/greensteel-eco-sync' into gree…
kbrunik May 21, 2024
28f28dc
update financial inputs.
kbrunik May 24, 2024
db88f3a
update greensteel and greenheart tests
kbrunik May 24, 2024
9dc2f1a
update tests with updated greenheart features
kbrunik May 24, 2024
2f65406
Merge branch 'greensteel-eco-sync' into gs-test-pr
jaredthomas68 May 27, 2024
4e3aa5c
fix input check
jaredthomas68 May 27, 2024
c8191e8
Merge pull request #36 from jaredthomas68/gs-test-pr
kbrunik Jun 5, 2024
4d55862
Merge remote-tracking branch 'upstream/greensteel-eco-sync' into gree…
kbrunik Jun 5, 2024
611ba48
update key value for ss storage
kbrunik Jun 6, 2024
093de7d
update examples with key changes
kbrunik Jun 6, 2024
2f42947
fixed h2 storage sizing bug
kbrunik Jun 6, 2024
81e55f8
clean up hydrogen mgmt logic
kbrunik Jun 7, 2024
137b6ae
fix typo
kbrunik Jun 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@

print("LCOE: ", lcoe, "[$/MWh]")
print("LCOH: ", lcoh, "[$/kg]")
print("LCOS: ", lcos, "[$/metric-tonne]")
print("LCOS: ", lcos, "[$/metric-tonne]")
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@

print("LCOE: ", lcoe, "[$/MWh]")
print("LCOH: ", lcoh, "[$/kg]")
print("LCOA: ", lcoa, "[$/kg]")
print("LCOA: ", lcoa, "[$/kg]")
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

# ORBIT imports
from ORBIT.core.library import initialize_library

initialize_library(os.path.join(os.getcwd(), "./input/"))

# run the stuff
Expand All @@ -32,7 +33,7 @@
filename_turbine_config = "./input/turbines/" + turbine_model + ".yaml"
filename_floris_config = "./input/floris/floris_input_osw_17MW.yaml"
filename_hopp_config = "./input/plant/hopp_config_gom.yaml"
filename_orbit_config= "./input/plant/orbit-config-"+turbine_model+"-gom.yaml"
filename_orbit_config = "./input/plant/orbit-config-" + turbine_model + "-gom.yaml"
filename_greenheart_config = "./input/plant/greenheart_config_offshore_gom.yaml"

config = GreenHeartSimulationConfig(
Expand Down Expand Up @@ -61,4 +62,4 @@
lcoh = prob.get_val("lcoh", units="USD/kg")

print("LCOE: ", lcoe, "[$/MWh]")
print("LCOH: ", lcoh, "[$/kg]")
print("LCOH: ", lcoh, "[$/kg]")
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

# ORBIT imports
from ORBIT.core.library import initialize_library

initialize_library(os.path.join(os.getcwd(), "./input/"))

# run the stuff
Expand All @@ -32,7 +33,7 @@
filename_turbine_config = "./input/turbines/" + turbine_model + ".yaml"
filename_floris_config = "./input/floris/floris_input_osw_15MW.yaml"
filename_hopp_config = "./input/plant/hopp_config_ny.yaml"
filename_orbit_config= "./input/plant/orbit-config-"+turbine_model+"-ny.yaml"
filename_orbit_config = "./input/plant/orbit-config-" + turbine_model + "-ny.yaml"
filename_greenheart_config = "./input/plant/greenheart_config_offshore_ny.yaml"

config = GreenHeartSimulationConfig(
Expand Down Expand Up @@ -61,4 +62,4 @@
lcoh = prob.get_val("lcoh", units="USD/kg")

print("LCOE: ", lcoe, "[$/MWh]")
print("LCOH: ", lcoh, "[$/kg]")
print("LCOH: ", lcoh, "[$/kg]")
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

# ORBIT imports
from ORBIT.core.library import initialize_library

initialize_library(os.path.join(os.getcwd(), "./input/"))

# run the stuff
Expand All @@ -32,7 +33,7 @@
filename_turbine_config = "./input/turbines/" + turbine_model + ".yaml"
filename_floris_config = "./input/floris/floris_input_osw_15MW.yaml"
filename_hopp_config = "./input/plant/hopp_config_ca.yaml"
filename_orbit_config= "./input/plant/orbit-config-"+turbine_model+"-ca.yaml"
filename_orbit_config = "./input/plant/orbit-config-" + turbine_model + "-ca.yaml"
filename_greenheart_config = "./input/plant/greenheart_config_offshore_ca.yaml"

config = GreenHeartSimulationConfig(
Expand Down Expand Up @@ -61,4 +62,4 @@
lcoh = prob.get_val("lcoh", units="USD/kg")

print("LCOE: ", lcoe, "[$/MWh]")
print("LCOH: ", lcoh, "[$/kg]")
print("LCOH: ", lcoh, "[$/kg]")
136 changes: 98 additions & 38 deletions greenheart/simulation/greenheart_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import greenheart.tools.eco.utilities as he_util
import greenheart.tools.eco.hydrogen_mgmt as he_h2


@define
class GreenHeartSimulationConfig:
"""
Expand Down Expand Up @@ -157,10 +158,10 @@ def __attrs_post_init__(self):
self.orbit_config["plant"]["num_turbines"] = int(
self.wind_rating * 1e-3 / self.turbine_config["turbine_rating"]
)
self.hopp_config["technologies"]["wind"]["num_turbines"] = (
self.orbit_config["plant"]["num_turbines"]
)
self.hopp_config["technologies"]["wind"][
"num_turbines"
] = self.orbit_config["plant"]["num_turbines"]

if self.grid_connection != None:
self.greenheart_config["project_parameters"][
"grid_connection"
Expand Down Expand Up @@ -238,38 +239,74 @@ def setup_greenheart_simulation(config: GreenHeartSimulationConfig):
# run orbit for wind plant construction and other costs
## TODO get correct weather (wind, wave) inputs for ORBIT input (possibly via ERA5)
if config.design_scenario["wind_location"] == "offshore":

if config.orbit_config["plant"]["num_turbines"] != config.hopp_config["technologies"]["wind"]["num_turbines"]:

if (
config.orbit_config["plant"]["num_turbines"]
!= config.hopp_config["technologies"]["wind"]["num_turbines"]
):
config.orbit_config["plant"].update(
{"num_turbines": config.hopp_config["technologies"]["wind"]["num_turbines"]}
{
"num_turbines": config.hopp_config["technologies"]["wind"][
"num_turbines"
]
}
)
warnings.warn(f"'num_turbines' in the orbit_config was {config.orbit_config['plant']['num_turbines']}, but 'num_turbines' in"
f"hopp_config was {config.hopp_config['technologies']['wind']['num_turbines']}. The 'num_turbines' value in the orbit_config"
"is being overwritten with the value from the hopp_config", UserWarning)

if config.orbit_config["site"]["depth"] != config.greenheart_config["site"]["depth"]:
warnings.warn(
f"'num_turbines' in the orbit_config was {config.orbit_config['plant']['num_turbines']}, but 'num_turbines' in"
f"hopp_config was {config.hopp_config['technologies']['wind']['num_turbines']}. The 'num_turbines' value in the orbit_config"
"is being overwritten with the value from the hopp_config",
UserWarning,
)

if (
config.orbit_config["site"]["depth"]
!= config.greenheart_config["site"]["depth"]
):
config.orbit_config["site"].update(
{"depth": config.greenheart_config["site"]["depth"]}
)
warnings.warn(f"site depth in the orbit_config was {config.orbit_config['site']['depth']}, but site depth in"
f"greenheart_config was {config.greenheart_config['site']['depth']}. The site depth value in the orbit_config"
"is being overwritten with the value from the greenheart_config", UserWarning)

if config.orbit_config["plant"]["turbine_spacing"] != config.greenheart_config["site"]["wind_layout"]["turbine_spacing"]:
config.orbit_config["plant"].update(
{"turbine_spacing": config.greenheart_config["site"]["wind_layout"]["turbine_spacing"]}
warnings.warn(
f"site depth in the orbit_config was {config.orbit_config['site']['depth']}, but site depth in"
f"greenheart_config was {config.greenheart_config['site']['depth']}. The site depth value in the orbit_config"
"is being overwritten with the value from the greenheart_config",
UserWarning,
)
warnings.warn(f"'turbine_spacing' in the orbit_config was {config.orbit_config['plant']['turbine_spacing']}, but 'turbine_spacing' in"
f"greenheart_config was {config.greenheart_config['site']['wind_layout']['turbine_spacing']}. The 'turbine_spacing' value in the orbit_config"
"is being overwritten with the value from the greenheart_config", UserWarning)

if config.orbit_config["plant"]["row_spacing"] != config.greenheart_config["site"]["wind_layout"]["row_spacing"]:
config.orbit_config["plant"].update(
{"row_spacing": config.greenheart_config["site"]["wind_layout"]["row_spacing"]}
{
"turbine_spacing": config.greenheart_config["site"]["wind_layout"][
"turbine_spacing"
]
}
)
warnings.warn(
f"site depth in the orbit_config was {config.orbit_config['plant']['turbine_spacing']}, but 'turbine_spacing' in"
f"greenheart_config was {config.greenheart_config['site']['wind_layout']['turbine_spacing']}. The 'turbine_spacing' value in the orbit_config"
"is being overwritten with the value from the greenheart_config",
UserWarning,
)

if (
config.orbit_config["plant"]["row_spacing"]
!= config.greenheart_config["site"]["wind_layout"]["row_spacing"]
):
config.orbit_config["plant"].update(
{
"row_spacing": config.greenheart_config["site"]["wind_layout"][
"row_spacing"
]
}
)
warnings.warn(
f"site depth in the orbit_config was {config.orbit_config['plant']['row_spacing']}, but 'row_spacing' in"
f"greenheart_config was {config.greenheart_config['site']['wind_layout']['row_spacing']}. The 'row_spacing' value in the orbit_config"
"is being overwritten with the value from the greenheart_config",
UserWarning,
kbrunik marked this conversation as resolved.
Show resolved Hide resolved
)
warnings.warn(f"site depth in the orbit_config was {config.orbit_config['plant']['row_spacing']}, but 'row_spacing' in"
f"greenheart_config was {config.greenheart_config['site']['wind_layout']['row_spacing']}. The 'row_spacing' value in the orbit_config"
"is being overwritten with the value from the greenheart_config", UserWarning)

wind_config = he_fin.WindCostConfig(
design_scenario=config.design_scenario,
Expand Down Expand Up @@ -368,7 +405,7 @@ def run_simulation(config: GreenHeartSimulationConfig):
hopp_config=config.hopp_config,
greenheart_config=config.greenheart_config,
turbine_config=config.turbine_config,
hopp_interface=hopp_results["hopp_interface"]
hopp_interface=hopp_results["hopp_interface"],
)

wind_cost_results = he_fin.run_wind_cost_model(
Expand Down Expand Up @@ -457,13 +494,14 @@ def energy_internals(
)

# compressor #TODO size correctly
h2_transport_compressor, h2_transport_compressor_results = (
he_h2.run_h2_transport_compressor(
config.greenheart_config,
electrolyzer_physics_results,
design_scenario,
verbose=verbose,
)
(
h2_transport_compressor,
h2_transport_compressor_results,
) = he_h2.run_h2_transport_compressor(
config.greenheart_config,
electrolyzer_physics_results,
design_scenario,
verbose=verbose,
)

# transport pipeline
Expand Down Expand Up @@ -814,6 +852,9 @@ def simple_solver(initial_guess=0.0):
if config.verbose:
print("Running ammonia\n")

if "hydrogen_cost" not in config.greenheart_config['ammonia']['costs']['feedstocks']:
config.greenheart_config['ammonia']['costs']['feedstocks']['hydrogen_cost'] = lcoh

# use the hydrogen amount from the electrolyzer physics model if it is not already in the config
if (
"hydrogen_amount_kgpy"
Expand Down Expand Up @@ -916,7 +957,13 @@ def simple_solver(initial_guess=0.0):
platform_results = platform_results
)

def run_sweeps(simulate=False, verbose=True, show_plots=True, use_profast=True, output_dir="output/"):
def run_sweeps(
simulate=False,
verbose=True,
show_plots=True,
use_profast=True,
output_dir="output/",
):

if simulate:
verbose = False
Expand All @@ -942,7 +989,8 @@ def run_sweeps(simulate=False, verbose=True, show_plots=True, use_profast=True,
)
print(lcoh_array)
np.savetxt(
output_dir + "data/lcoh_vs_rating_%s_storage_%sMWwindplant.txt"
output_dir
+ "data/lcoh_vs_rating_%s_storage_%sMWwindplant.txt"
% (storage_type, wind_rating),
np.c_[ratings, lcoh_array],
)
Expand Down Expand Up @@ -1033,7 +1081,11 @@ def run_sweeps(simulate=False, verbose=True, show_plots=True, use_profast=True,


def run_policy_options_storage_types(
verbose=True, show_plots=False, save_plots=False, use_profast=True, output_dir="output/"
verbose=True,
show_plots=False,
save_plots=False,
use_profast=True,
output_dir="output/",
):

storage_types = ["pressure_vessel", "pipe", "salt_cavern", "none"]
Expand Down Expand Up @@ -1066,7 +1118,11 @@ def run_policy_options_storage_types(


def run_policy_storage_design_options(
verbose=False, show_plots=False, save_plots=False, use_profast=True, output_dir="output/"
verbose=False,
show_plots=False,
save_plots=False,
use_profast=True,
output_dir="output/",
):

design_scenarios = [1, 2, 3, 4, 5, 6, 7]
Expand Down Expand Up @@ -1156,7 +1212,11 @@ def run_policy_storage_design_options(


def run_design_options(
verbose=False, show_plots=False, save_plots=False, incentive_option=1, output_dir="output/"
verbose=False,
show_plots=False,
save_plots=False,
incentive_option=1,
output_dir="output/",
):

design_options = range(1, 8) # 8
Expand Down Expand Up @@ -1232,7 +1292,7 @@ def run_storage_options(output_dir="output/"):
storage_type=storage_type,
output_level=4,
grid_connection=False,
output_dir=output_dir
output_dir=output_dir,
)
lcoe_list.append(lcoe)
lcoh_list.append(lcoh)
Expand All @@ -1248,7 +1308,7 @@ def run_storage_options(output_dir="output/"):
storage_type=storage_type,
output_level=4,
grid_connection=True,
output_dir=output_dir
output_dir=output_dir,
)
lcoh_with_grid_list.append(lcoh_with_grid)
lcoh_grid_only_list.append(lcoh_grid_only)
Expand Down
11 changes: 8 additions & 3 deletions greenheart/tools/eco/electrolysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import matplotlib.pyplot as plt
from matplotlib import ticker
import os
import warnings
from greenheart.tools.eco.utilities import ceildiv

# import hopp.tools.hopp_tools as hopp_tools
Expand Down Expand Up @@ -87,6 +88,9 @@ def run_electrolyzer_physics(
"turndown_ratio": greenheart_config["electrolyzer"]["turndown_ratio"],
}

if "time_between_replacement" in greenheart_config['electrolyzer']:
warnings.warn("`time_between_replacement` as an input is depricated. It is now calculated internally and is output in electrolyzer_physics_results['H2_Results']['Time Until Replacement [hrs]'].")
kbrunik marked this conversation as resolved.
Show resolved Hide resolved

H2_Results, h2_ts, h2_tot, power_to_electrolyzer_kw = run_h2_PEM(
electrical_generation_timeseries=energy_to_electrolyzer_kw,
electrolyzer_size=electrolyzer_size_mw,
Expand Down Expand Up @@ -392,9 +396,10 @@ def run_electrolyzer_cost(

pem_offshore = PEMCostsSingliticoModel(elec_location=offshore)

electrolyzer_capital_cost_musd, electrolyzer_om_cost_musd = (
pem_offshore.run(P_elec, RC_elec)
)
(
electrolyzer_capital_cost_musd,
electrolyzer_om_cost_musd,
) = pem_offshore.run(P_elec, RC_elec)

electrolyzer_total_capital_cost = (
electrolyzer_capital_cost_musd * 1e6
Expand Down
Loading
Loading