Skip to content
Open
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
2 changes: 1 addition & 1 deletion examples/01_onshore_steel_mn/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
dispatch_rule_parameters:
commodity_name: "electricity"
commodity_storage_units: "kW"
Expand Down
2 changes: 1 addition & 1 deletion examples/02_texas_ammonia/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
dispatch_rule_parameters:
commodity_name: "electricity"
commodity_storage_units: "kW"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
electrolyzer:
performance_model:
model: "ECOElectrolyzerPerformanceModel"
Expand Down
2 changes: 1 addition & 1 deletion examples/09_co2/direct_ocean_capture/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
dispatch_rule_parameters:
commodity_name: "electricity"
commodity_storage_units: "kW"
Expand Down
2 changes: 1 addition & 1 deletion examples/12_ammonia_synloop/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
dispatch_rule_parameters:
commodity_name: "electricity"
commodity_storage_units: "kW"
Expand Down
2 changes: 1 addition & 1 deletion examples/15_wind_solar_electrolyzer/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
electrolyzer:
performance_model:
model: "ECOElectrolyzerPerformanceModel"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ technologies:
model_inputs:
performance_parameters:
commodity: electricity
commodity_units: kW
commodity_rate_units: kW
2 changes: 1 addition & 1 deletion examples/23_solar_wind_ng_demand/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ technologies:
model_inputs:
performance_parameters:
commodity: electricity
commodity_units: kW
commodity_rate_units: kW
2 changes: 1 addition & 1 deletion examples/26_floris/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ technologies:
model_inputs:
performance_parameters:
commodity: electricity
commodity_units: kW
commodity_rate_units: kW
2 changes: 1 addition & 1 deletion examples/27_site_doe_diff/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ technologies:
model_inputs:
performance_parameters:
commodity: "electricity"
commodity_units: "kW"
commodity_rate_units: "kW"
2 changes: 1 addition & 1 deletion examples/29_wind_ard/h2i_inputs/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ technologies:
model_inputs:
performance_parameters:
commodity: electricity
commodity_units: kW
commodity_rate_units: kW
battery:
performance_model:
model: "SimpleGenericStorage"
Expand Down
27 changes: 27 additions & 0 deletions examples/test/test_all_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,33 @@ def test_co2h_methanol_example(subtests):

model.post_process()

# Below is used as an integration test for the combiner
with subtests.test("combiner rated production"):
combined_rated_input = model.prob.get_val(
"wind.rated_electricity_production", units="MW"
) + model.prob.get_val("solar.rated_electricity_production", units="MW")
assert (
pytest.approx(
model.prob.get_val("combiner.rated_electricity_production", units="MW"), rel=1e-6
)
== combined_rated_input
)
with subtests.test("combiner weighted CF"):
wind_weighted_cf = model.prob.get_val(
"wind.rated_electricity_production", units="MW"
) * model.prob.get_val("wind.capacity_factor", units="unitless")
solar_weighted_cf = model.prob.get_val(
"solar.rated_electricity_production", units="MW"
) * model.prob.get_val("solar.capacity_factor", units="unitless")
combined_cf = (wind_weighted_cf + solar_weighted_cf) / combined_rated_input
assert (
pytest.approx(
model.prob.get_val("combiner.electricity_capacity_factor", units="unitless"),
rel=1e-6,
)
== combined_cf
)

# Check levelized cost of methanol (LCOM)
with subtests.test("Check CO2 Hydrogenation LCOM"):
assert pytest.approx(model.prob.get_val("methanol.LCOM")[0], rel=1e-6) == 1.7555607442
Expand Down
13 changes: 12 additions & 1 deletion h2integrate/core/h2integrate_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,9 @@ def create_finance_model(self):
"model_inputs": {
"performance_parameters": {
"commodity": commodity,
"commodity_units": "kW" if commodity == "electricity" else "kg/h",
"commodity_rate_units": "kW"
if commodity == "electricity"
else "kg/h",
}
}
}
Expand Down Expand Up @@ -970,6 +972,15 @@ def connect_technologies(self):
f"{connection_name}.{transport_item}_out",
f"{dest_tech}.{transport_item}_in{combiner_counts[dest_tech]}",
)
# Connect the source tech design and performance info to the combiner
self.plant.connect(
f"{source_tech}.rated_{transport_item}_production",
f"{dest_tech}.rated_{transport_item}_production{combiner_counts[dest_tech]}",
)
self.plant.connect(
f"{source_tech}.capacity_factor",
f"{dest_tech}.{transport_item}_capacity_factor{combiner_counts[dest_tech]}",
)

elif "storage" in dest_tech:
# Connect the connection component to the destination technology
Expand Down
58 changes: 52 additions & 6 deletions h2integrate/transporters/generic_combiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class GenericCombinerPerformanceConfig(BaseConfig):
"""

commodity: str = field(converter=(str.lower, str.strip))
commodity_units: str = field()
commodity_rate_units: str = field()
in_streams: int = field(default=2)


Expand All @@ -39,25 +39,71 @@ def setup(self):
)

n_timesteps = int(self.options["plant_config"]["plant"]["simulation"]["n_timesteps"])
plant_life = int(self.options["plant_config"]["plant"]["plant_life"])

for i in range(1, self.config.in_streams + 1):
self.add_input(
f"{self.config.commodity}_in{i}",
val=0.0,
shape=n_timesteps,
units=self.config.commodity_units,
units=self.config.commodity_rate_units,
)
self.add_input(
f"rated_{self.config.commodity}_production{i}",
val=0.0,
shape=1,
units=self.config.commodity_rate_units,
)
self.add_input(
f"{self.config.commodity}_capacity_factor{i}",
val=0.0,
shape=plant_life,
units="unitless",
)

self.add_output(
f"{self.config.commodity}_out",
val=0.0,
shape=n_timesteps,
units=self.config.commodity_units,
units=self.config.commodity_rate_units,
)
self.add_output(
f"{self.config.commodity}_capacity_factor",
val=0.0,
shape=plant_life,
units="unitless",
)
self.add_output(
f"rated_{self.config.commodity}_production",
val=0.0,
shape=1,
units=self.config.commodity_rate_units,
)

def compute(self, inputs, outputs):
total = 0.0
total_out = 0.0
weighted_cf = 0.0
total_rated = 0.0
for key, value in inputs.items():
if "_in" in key:
total = total + value
outputs[f"{self.config.commodity}_out"] = total
# add the commodity_in profile
total_out = total_out + value
if key.startswith("rated_"):
# add the rated_commodity_production
total_rated = total_rated + value
if "_capacity_factor" in key:
# get the stream number so we can get the proper rated capacity
stream_number = key.split("capacity_factor")[-1]
rated_capacity = inputs[f"rated_{self.config.commodity}_production{stream_number}"]
# weight the capacity factor with the rated capacity
weighted_cf = weighted_cf + (value * rated_capacity)

outputs[f"{self.config.commodity}_out"] = total_out
outputs[f"rated_{self.config.commodity}_production"] = total_rated
if total_rated > 0:
# weighted CF = (CF1*S1 + CF2*S2)/(S1 + S2)
# Where S is the rated commodity production of input stream i
# and CF is the capacity factor of input stream i
outputs[f"{self.config.commodity}_capacity_factor"] = weighted_cf / total_rated
else:
outputs[f"{self.config.commodity}_capacity_factor"] = 0.0
8 changes: 4 additions & 4 deletions h2integrate/transporters/generic_summer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class GenericSummerPerformanceConfig(BaseConfig):
"""

commodity: str = field(converter=(str.lower, str.strip))
commodity_units: str = field()
commodity_rate_units: str = field()
operation_mode: str = field(
default="production",
converter=(str.lower, str.strip),
Expand Down Expand Up @@ -46,15 +46,15 @@ def setup(self):
if self.config.commodity == "electricity":
# NOTE: this should be updated in overhaul required for flexible dt
# and flexible simulation length
summed_units = f"{self.config.commodity_units}*h/year"
summed_units = f"{self.config.commodity_rate_units}*h/year"
else:
summed_units = f"{self.config.commodity_units}*h/year"
summed_units = f"{self.config.commodity_rate_units}*h/year"

self.add_input(
f"{self.config.commodity}_in",
val=0.0,
shape=n_timesteps,
units=self.config.commodity_units,
units=self.config.commodity_rate_units,
)

if self.config.operation_mode == "consumption":
Expand Down
46 changes: 35 additions & 11 deletions h2integrate/transporters/test/test_generic_combiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def plant_config():
def combiner_tech_config_electricity():
elec_combiner_dict = {
"model_inputs": {
"performance_parameters": {"commodity": "electricity", "commodity_units": "kW"}
"performance_parameters": {"commodity": "electricity", "commodity_rate_units": "kW"}
}
}
return elec_combiner_dict
Expand All @@ -36,7 +36,7 @@ def combiner_tech_config_electricity_4_in():
"model_inputs": {
"performance_parameters": {
"commodity": "electricity",
"commodity_units": "kW",
"commodity_rate_units": "kW",
"in_streams": 4,
}
}
Expand All @@ -48,7 +48,7 @@ def combiner_tech_config_electricity_4_in():
def combiner_tech_config_hydrogen():
h2_combiner_dict = {
"model_inputs": {
"performance_parameters": {"commodity": "hydrogen", "commodity_units": "kg"}
"performance_parameters": {"commodity": "hydrogen", "commodity_rate_units": "kg"}
}
}
return h2_combiner_dict
Expand All @@ -60,7 +60,7 @@ def summer_tech_config_electricity_consumption():
"model_inputs": {
"performance_parameters": {
"commodity": "electricity",
"commodity_units": "kW",
"commodity_rate_units": "kW",
"operation_mode": "consumption",
}
}
Expand All @@ -74,7 +74,7 @@ def summer_tech_config_hydrogen_consumption():
"model_inputs": {
"performance_parameters": {
"commodity": "hydrogen",
"commodity_units": "kg",
"commodity_rate_units": "kg",
"operation_mode": "consumption",
}
}
Expand All @@ -88,7 +88,7 @@ def summer_tech_config_electricity_production():
"model_inputs": {
"performance_parameters": {
"commodity": "electricity",
"commodity_units": "kW",
"commodity_rate_units": "kW",
"operation_mode": "production",
}
}
Expand All @@ -102,15 +102,17 @@ def summer_tech_config_hydrogen_production():
"model_inputs": {
"performance_parameters": {
"commodity": "hydrogen",
"commodity_units": "kg",
"commodity_rate_units": "kg",
"operation_mode": "production",
}
}
}
return h2_summer_dict


def test_generic_combiner_performance_power(plant_config, combiner_tech_config_electricity):
def test_generic_combiner_performance_power(
plant_config, combiner_tech_config_electricity, subtests
):
prob = om.Problem()
comp = GenericCombinerPerformanceModel(
plant_config=plant_config, tech_config=combiner_tech_config_electricity, driver_config={}
Expand All @@ -119,19 +121,41 @@ def test_generic_combiner_performance_power(plant_config, combiner_tech_config_e
ivc = om.IndepVarComp()
ivc.add_output("electricity_in1", val=np.zeros(8760), units="kW")
ivc.add_output("electricity_in2", val=np.zeros(8760), units="kW")
ivc.add_output("rated_electricity_production1", val=0, units="kW")
ivc.add_output("rated_electricity_production2", val=0, units="kW")
ivc.add_output("electricity_capacity_factor1", val=np.zeros(30), units="unitless")
ivc.add_output("electricity_capacity_factor2", val=np.zeros(30), units="unitless")
prob.model.add_subsystem("ivc", ivc, promotes=["*"])

prob.setup()

electricity_input1 = rng.random(8760)
electricity_input2 = rng.random(8760)
electricity_output = electricity_input1 + electricity_input2

rated_electricity_output = np.max(electricity_input1) + np.max(electricity_input2)
cf_input1 = np.sum(electricity_input1) / (np.max(electricity_input1) * len(electricity_input1))
cf_input2 = np.sum(electricity_input2) / (np.max(electricity_input2) * len(electricity_input2))
prob.set_val("electricity_in1", electricity_input1, units="kW")
prob.set_val("electricity_in2", electricity_input2, units="kW")
prob.set_val("rated_electricity_production1", np.max(electricity_input1), units="kW")
prob.set_val("rated_electricity_production2", np.max(electricity_input2), units="kW")
prob.set_val("electricity_capacity_factor1", cf_input1 * np.ones(30), units="unitless")
prob.set_val("electricity_capacity_factor2", cf_input2 * np.ones(30), units="unitless")
prob.run_model()

assert prob.get_val("electricity_out", units="kW") == approx(electricity_output, rel=1e-5)
with subtests.test("combined electricity_out"):
assert prob.get_val("electricity_out", units="kW") == approx(electricity_output, rel=1e-5)
with subtests.test("combined rated_electricity_production"):
assert prob.get_val("rated_electricity_production", units="kW") == approx(
rated_electricity_output, rel=1e-5
)
with subtests.test("combined electricity_capacity_factor"):
combined_cf = np.sum(electricity_output) / (
rated_electricity_output * len(electricity_output)
)
assert prob.get_val("electricity_capacity_factor", units="unitless") == approx(
combined_cf, rel=1e-5
)


def test_generic_combiner_performance_power_4_in(
Expand Down Expand Up @@ -304,7 +328,7 @@ def test_generic_summer_default_mode_is_production(plant_config):
"model_inputs": {
"performance_parameters": {
"commodity": "electricity",
"commodity_units": "kW",
"commodity_rate_units": "kW",
# Note: operation_mode not specified, should default to production
}
}
Expand Down