Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
- Updated option to pass variables in technology interconnections to allow for different variable names from source to destination in the format `[source_tech, dest_tech, (source_tech_variable, dest_tech_variable)]`
- Added `simulation` section under `plant_config['plant']` that has information such as number of timesteps in the simulation, time step interval in seconds, simulation start time, and time zone.
- Added `"custom_electrolyzer_cost"` model, an electrolyzer cost model that allows for user-defined capex and opex values
- Made `pipe` and `cable` substance-agnostic rather than hard-coded for `hydrogen` and `electricity`

## 0.3.0 [May 2 2025]

Expand Down
6 changes: 3 additions & 3 deletions examples/05_wind_h2_opt/driver_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ general:
driver:
optimization:
flag: True
solver: COBYLA
tol: 0.1
catol: 10000
max_iter: 100
solver: COBYLA
rhobeg: 30
rhobeg: 10
debug_print: True

design_variables:
Expand All @@ -35,4 +35,4 @@ objective:
recorder:
flag: True
file: "wind_h2_opt.sql"
includes: ["LCOH"]
includes: ["*"]
4 changes: 3 additions & 1 deletion h2integrate/core/h2integrate_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,9 @@ def connect_technologies(self):
connection_name = f"{source_tech}_to_{dest_tech}_{transport_type}"

# Create the transport object
connection_component = self.supported_models[transport_type]()
connection_component = self.supported_models[transport_type](
transport_item=transport_item
)

# Add the connection component to the model
self.plant.add_subsystem(connection_name, connection_component)
Expand Down
15 changes: 10 additions & 5 deletions h2integrate/transporters/cable.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,26 @@ class CablePerformanceModel(om.ExplicitComponent):
Pass-through cable with no losses.
"""

def initialize(self):
self.options.declare("transport_item", values=["electricity"])

def setup(self):
self.input_name = self.options["transport_item"] + "_in"
self.output_name = self.options["transport_item"] + "_out"
self.add_input(
"electricity_in",
self.input_name,
val=0.0,
shape_by_conn=True,
copy_shape="electricity_out",
copy_shape=self.output_name,
units="kW",
)
self.add_output(
"electricity_out",
self.output_name,
val=0.0,
shape_by_conn=True,
copy_shape="electricity_in",
copy_shape=self.input_name,
units="kW",
)

def compute(self, inputs, outputs):
outputs["electricity_out"] = inputs["electricity_in"]
outputs[self.output_name] = inputs[self.input_name]
17 changes: 12 additions & 5 deletions h2integrate/transporters/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,28 @@ class PipePerformanceModel(om.ExplicitComponent):
Pass-through pipe with no losses.
"""

def initialize(self):
self.options.declare(
"transport_item", values=["hydrogen", "co2", "methanol", "ammonia", "nitrogen"]
)

def setup(self):
self.input_name = self.options["transport_item"] + "_in"
self.output_name = self.options["transport_item"] + "_out"
self.add_input(
"hydrogen_in",
self.input_name,
val=0.0,
shape_by_conn=True,
copy_shape="hydrogen_out",
copy_shape=self.output_name,
units="kg/s",
)
self.add_output(
"hydrogen_out",
self.output_name,
val=0.0,
shape_by_conn=True,
copy_shape="hydrogen_in",
copy_shape=self.input_name,
units="kg/s",
)

def compute(self, inputs, outputs):
outputs["hydrogen_out"] = inputs["hydrogen_in"]
outputs[self.output_name] = inputs[self.input_name]
40 changes: 40 additions & 0 deletions h2integrate/transporters/test/test_pipe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pytest
import openmdao.api as om
from pytest import approx

from h2integrate.transporters.pipe import PipePerformanceModel


def test_pipe_with_hydrogen():
"""Test the pipe transport with hydrogen as transport_item."""

# Create the pipe component with hydrogen as transport item
pipe = PipePerformanceModel(transport_item="hydrogen")

# Create OpenMDAO problem and add the component
prob = om.Problem()
prob.model.add_subsystem("pipe", pipe, promotes=["*"])

# Add independent variable component for input
ivc = om.IndepVarComp()
ivc.add_output("hydrogen_in", val=10.0, units="kg/s")
prob.model.add_subsystem("ivc", ivc, promotes=["*"])

# Setup and run the model
prob.setup()
prob.set_val("hydrogen_in", 10.0, units="kg/s")
prob.run_model()

# Check that output equals input (pass-through pipe with no losses)
hydrogen_in = prob.get_val("hydrogen_in", units="kg/s")
hydrogen_out = prob.get_val("hydrogen_out", units="kg/s")

assert hydrogen_out == approx(hydrogen_in, rel=1e-10)
assert hydrogen_out == approx(10.0, rel=1e-10)


def test_pipe_with_invalid_transport_item():
"""Test that pipe raises an error with invalid transport_item."""
with pytest.raises(ValueError) as excinfo:
PipePerformanceModel(transport_item="invalid_item")
assert "Value ('invalid_item')" in str(excinfo.value)