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

Rudimentary hydrogen dispatch estimation and saving hydrogen SOC #329

31 changes: 29 additions & 2 deletions greenheart/simulation/greenheart_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ class GreenHeartSimulationOutput:
remaining_power_profile: np.ndarray

# optional outputs
h2_storage_max_fill_rate_kg_hr: Optional[dict] = field(default=None)
h2_storage_capacity_kg: Optional[dict] = field(default=None)
hydrogen_storage_state_of_charge_kg: Optional[dict] = field(default=None)

steel_capacity: Optional[SteelCapacityModelOutputs] = field(default=None)
steel_costs: Optional[SteelCostModelOutputs] = field(default=None)
steel_finance: Optional[SteelFinanceModelOutputs] = field(default=None)
Expand Down Expand Up @@ -944,12 +948,35 @@ def simple_solver(initial_guess=0.0):
annual_energy_breakdown,
hourly_energy_breakdown,
remaining_power_profile,
h2_storage_max_fill_rate_kg_hr = (
None
if "h2_storage_max_fill_rate_kg_hr" not in h2_storage_results
else h2_storage_results["h2_storage_max_fill_rate_kg_hr"]
),
h2_storage_capacity_kg = (
None
if "h2_storage_capacity_kg" not in h2_storage_results
else h2_storage_results["h2_storage_capacity_kg"]
),
hydrogen_storage_state_of_charge_kg = (
None
if "hydrogen_storage_soc" not in h2_storage_results
else h2_storage_results["hydrogen_storage_soc"]
),
steel_capacity = None if "steel" not in config.greenheart_config else steel_capacity,
steel_costs = None if "steel" not in config.greenheart_config else steel_costs,
steel_finance = None if "steel" not in config.greenheart_config else steel_finance,
ammonia_capacity = None if "ammonia" not in config.greenheart_config else ammonia_capacity,
ammonia_capacity = (
None
if "ammonia" not in config.greenheart_config
else ammonia_capacity
),
ammonia_costs = None if "ammonia" not in config.greenheart_config else ammonia_costs,
ammonia_finance = None if "ammonia" not in config.greenheart_config else ammonia_finance,
ammonia_finance = (
None
if "ammonia" not in config.greenheart_config
else ammonia_finance
),
platform_results = platform_results
)

Expand Down
32 changes: 27 additions & 5 deletions greenheart/tools/eco/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -1371,7 +1371,14 @@ def add_turbines(ax, turbine_x, turbine_y, radius, color):


def save_energy_flows(
hybrid_plant: HoppInterface.system, electrolyzer_physics_results, solver_results, hours, ax=None, simulation_length=8760, output_dir="./output/",
hybrid_plant: HoppInterface.system,
electrolyzer_physics_results,
solver_results,
hours,
h2_storage_results,
ax=None,
simulation_length=8760,
output_dir="./output/",
):


Expand Down Expand Up @@ -1408,6 +1415,8 @@ def save_energy_flows(
output.update({"transport compressor energy hourly [kW]": [solver_results[3]]*simulation_length})
output.update({"storage energy hourly [kW]": [solver_results[4]]*simulation_length})
output.update({"h2 production hourly [kg]": electrolyzer_physics_results["H2_Results"]["Hydrogen Hourly Production [kg/hr]"]})
if "hydrogen_storage_soc" in h2_storage_results:
output.update({"hydrogen storage SOC [kg]": h2_storage_results["hydrogen_storage_soc"]})

df = pd.DataFrame.from_dict(output)

Expand Down Expand Up @@ -1561,6 +1570,7 @@ def post_process_simulation(
"h2_storage_power_kwh": solver_results[4] * hours,
}


######################### save detailed ORBIT cost information
if wind_cost_results.orbit_project:
_, orbit_capex_breakdown, wind_capex_multiplier = adjust_orbit_costs(
Expand Down Expand Up @@ -1664,14 +1674,26 @@ def post_process_simulation(
)
else:
print(
"generation profile not plotted because HoppInterface does not have a 'dispatch_builder'"
"generation profile not plotted because HoppInterface does not have a "
"'dispatch_builder'"
)

# save production information
hourly_energy_breakdown = save_energy_flows(hopp_results["hybrid_plant"], electrolyzer_physics_results, solver_results, hours)

hourly_energy_breakdown = save_energy_flows(
hopp_results["hybrid_plant"],
electrolyzer_physics_results,
solver_results,
hours,
h2_storage_results,
output_dir=output_dir
)

# save hydrogen information
key = "Hydrogen Hourly Production [kg/hr]"
np.savetxt(output_dir+"h2_usage", electrolyzer_physics_results["H2_Results"][key], header="# "+key)
np.savetxt(
output_dir + "h2_usage",
electrolyzer_physics_results["H2_Results"][key],
header="# " + key
)

return annual_energy_breakdown, hourly_energy_breakdown
Loading