Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 docs/control/control_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ The second systematic control approach, [pyomo control](#pyomo-control), allows
In the pyomo control framework in H2Integrate, each technology can have control rules associated with them that are in turn passed to the pyomo control component, which is owned by the storage technology. The pyomo control component combines the technology rules into a single pyomo model, which is then passed to the storage technology performance model inside a callable dispatch function. The dispatch function also accepts a simulation method from the performance model and iterates between the pyomo model for dispatch commands and the performance simulation function to simulated performance with the specified commands. The dispatch function runs in specified time windows for dispatch and performance until the whole simulation time has been run.

Supported controllers:
- [`HeuristicLoadFollowingController`](#heuristic-load-following-controller)
- [`HeuristicLoadFollowingStorageController`](#heuristic-load-following-controller)
8 changes: 4 additions & 4 deletions docs/control/pyomo_controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ The Pyomo control framework currently supports both a simple heuristic method an
(heuristic-load-following-controller)=
## Heuristic Load Following Controller

The simple heuristic method is specified by setting the storage control to `HeuristicLoadFollowingController`. When using the Pyomo framework, a `dispatch_rule_set` for each technology connected to the storage technology must also be specified. These will typically be `PyomoDispatchGenericConverter` for generating technologies, and `PyomoRuleStorageBaseclass` for storage technologies. More complex rule sets may be developed as needed.
The simple heuristic method is specified by setting the storage control to `HeuristicLoadFollowingStorageController`. When using the Pyomo framework, a `dispatch_rule_set` for each technology connected to the storage technology must also be specified. These will typically be `PyomoDispatchGenericConverter` for generating technologies, and `PyomoRuleStorageBaseclass` for storage technologies. More complex rule sets may be developed as needed.

For an example of how to use the heuristic Pyomo control framework with the `HeuristicLoadFollowingController`, see
For an example of how to use the heuristic Pyomo control framework with the `HeuristicLoadFollowingStorageController`, see
- `examples/18_pyomo_heuristic_wind_battery_dispatch`


(optimized-load-following-controller)=
## Optimized Load Following Controller
The optimized dispatch method is specified by setting the storage control to `OptimizedDispatchController`. Unlike the heuristic method, the optimized dispatch method does not use `dispatch_rule_set` as an input in the `tech_config`. The `OptimizedDispatchController` method maximizes the load met while minimizing the cost of the system (operating cost) over each specified time window.
The optimized dispatch method is specified by setting the storage control to `OptimizedDispatchStorageController`. Unlike the heuristic method, the optimized dispatch method does not use `dispatch_rule_set` as an input in the `tech_config`. The `OptimizedDispatchStorageController` method maximizes the load met while minimizing the cost of the system (operating cost) over each specified time window.

The optimized dispatch using Pyomo is implemented differently than the heuristic dispatch in order to be able to properly aggregate the individual Pyomo technology models into a cohesive Pyomo plant model for the optimization solver. Practically, this means that the Pyomo elements of the dispatch (including the individual technology models and the plant model) are not exposed to the main H2I code flow, and do not appear in the N2 diagram. The figure below shows a flow diagram of how the dispatch is implemented. The green blocks below represent what is represented in the N2 diagram of the system. The dispatch routine is currently self-contained within the storage technology of the system, though it includes solving an aggregated plant model in the optimization

Expand All @@ -40,7 +40,7 @@ We have exposed the optimization cost (weighting) values to the user in this imp
- The cost values are defined in units of "$/kW".
```

For an example of how to use the optimized Pyomo control framework with the `OptimizedDispatchController`, see
For an example of how to use the optimized Pyomo control framework with the `OptimizedDispatchStorageController`, see
- `examples/27_pyomo_optimized_dispatch`


Expand Down
4 changes: 2 additions & 2 deletions docs/user_guide/model_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,9 @@ Below summarizes the available performance, cost, and financial models for each
- Storage Controllers:
- `'SimpleStorageOpenLoopController'`: open-loop control; manages resource flow based on demand and input commodity
- `'DemandOpenLoopStorageController'`: open-loop control; manages resource flow based on demand and storage constraints
- `'HeuristicLoadFollowingController'`: open-loop control that works on a time window basis to set dispatch commands; uses Pyomo
- `'HeuristicLoadFollowingStorageController'`: open-loop control that works on a time window basis to set dispatch commands; uses Pyomo
- Optimized Dispatch:
- `'OptimizedDispatchController'`: optimization-based dispatch using Pyomo
- `'OptimizedDispatchStorageController'`: optimization-based dispatch using Pyomo

(demand-models)=
## Demand Models
Expand Down
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 @@ -67,7 +67,7 @@ technologies:
dispatch_rule_set:
model: PyomoRuleStorageBaseclass
control_strategy:
model: HeuristicLoadFollowingController
model: HeuristicLoadFollowingStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
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 @@ -67,7 +67,7 @@ technologies:
dispatch_rule_set:
model: PyomoRuleStorageBaseclass
control_strategy:
model: HeuristicLoadFollowingController
model: HeuristicLoadFollowingStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
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 @@ -59,7 +59,7 @@ technologies:
dispatch_rule_set:
model: PyomoRuleStorageBaseclass
control_strategy:
model: HeuristicLoadFollowingController
model: HeuristicLoadFollowingStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ technologies:
dispatch_rule_set:
model: PyomoRuleStorageBaseclass
control_strategy:
model: HeuristicLoadFollowingController
model: HeuristicLoadFollowingStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
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 @@ -67,7 +67,7 @@ technologies:
dispatch_rule_set:
model: PyomoRuleStorageBaseclass
control_strategy:
model: HeuristicLoadFollowingController
model: HeuristicLoadFollowingStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
Expand Down
2 changes: 1 addition & 1 deletion examples/18_pyomo_heuristic_dispatch/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ technologies:
dispatch_rule_set:
model: PyomoRuleStorageBaseclass
control_strategy:
model: HeuristicLoadFollowingController
model: HeuristicLoadFollowingStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
Expand Down
2 changes: 1 addition & 1 deletion examples/30_pyomo_optimized_dispatch/tech_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ technologies:
commodity_rate_units: kW
battery:
control_strategy:
model: OptimizedDispatchController
model: OptimizedDispatchStorageController
performance_model:
model: PySAMBatteryPerformanceModel
cost_model:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def dispatch_block_rule_function(self, pyomo_model: pyo.ConcreteModel):
This method sets up all model elements (parameters, variables, constraints,
and ports) associated with a technology block within the dispatch model.
It is typically called in the setup_pyomo() method of the PyomoControllerBaseClass.
It is typically called in the setup_pyomo() method of the PyomoStorageControllerBaseClass.
Args:
pyomo_model (pyo.ConcreteModel): The Pyomo model to which the technology
Expand Down
2 changes: 1 addition & 1 deletion h2integrate/control/control_rules/pyomo_rule_baseclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def dispatch_block_rule_function(self, pyomo_model: pyo.ConcreteModel, tech_name
This method sets up all model elements (parameters, variables, constraints,
and ports) associated with a technology block within the dispatch model.
It is typically called in the setup_pyomo() method of the PyomoControllerBaseClass.
It is typically called in the setup_pyomo() method of the PyomoStorageControllerBaseClass.
Args:
pyomo_model (pyo.ConcreteModel): The Pyomo model to which the technology
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

from h2integrate.core.utilities import merge_shared_inputs
from h2integrate.core.validators import range_val_or_none
from h2integrate.control.control_strategies.pyomo_controller_baseclass import (
PyomoControllerBaseClass,
PyomoControllerBaseConfig,
from h2integrate.control.control_strategies.storage.pyomo_controller_baseclass import (
PyomoStorageControllerBaseClass,
PyomoStorageControllerBaseConfig,
)


Expand All @@ -17,8 +17,8 @@


@define(kw_only=True)
class HeuristicLoadFollowingControllerConfig(PyomoControllerBaseConfig):
"""Configuration class for the HeuristicLoadFollowingController.
class HeuristicLoadFollowingStorageControllerConfig(PyomoStorageControllerBaseConfig):
"""Configuration class for the HeuristicLoadFollowingStorageController.

Attributes:
charge_efficiency (float | None, optional): Efficiency of charging the storage, represented
Expand Down Expand Up @@ -61,7 +61,7 @@ def __attrs_post_init__(self):
self.discharge_efficiency = np.sqrt(self.round_trip_efficiency)


class HeuristicLoadFollowingController(PyomoControllerBaseClass):
class HeuristicLoadFollowingStorageController(PyomoStorageControllerBaseClass):
"""Operates storage based on heuristic rules to meet the demand profile based on
available commodity from generation profiles and demand profile.

Expand All @@ -77,7 +77,7 @@ class HeuristicLoadFollowingController(PyomoControllerBaseClass):

def setup(self):
"""Initialize the heuristic load-following controller."""
self.config = HeuristicLoadFollowingControllerConfig.from_dict(
self.config = HeuristicLoadFollowingStorageControllerConfig.from_dict(
merge_shared_inputs(self.options["tech_config"]["model_inputs"], "control"),
additional_cls_name=self.__class__.__name__,
strict=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
from h2integrate.core.utilities import merge_shared_inputs
from h2integrate.core.validators import range_val
from h2integrate.control.control_rules.plant_dispatch_model import PyomoDispatchPlantModel
from h2integrate.control.control_strategies.pyomo_controller_baseclass import (
from h2integrate.control.control_strategies.storage.pyomo_controller_baseclass import (
SolverOptions,
PyomoControllerBaseClass,
PyomoControllerBaseConfig,
PyomoStorageControllerBaseClass,
PyomoStorageControllerBaseConfig,
)
from h2integrate.control.control_strategies.storage.controller_opt_problem_state import (
DispatchProblemState,
)
from h2integrate.control.control_strategies.controller_opt_problem_state import DispatchProblemState
from h2integrate.control.control_rules.storage.pyomo_storage_rule_min_operating_cost import (
PyomoRuleStorageMinOperatingCosts,
)
Expand All @@ -27,7 +29,7 @@


@define
class OptimizedDispatchControllerConfig(PyomoControllerBaseConfig):
class OptimizedDispatchStorageControllerConfig(PyomoStorageControllerBaseConfig):
"""
Configuration data container for Pyomo-based optimal dispatch.

Expand Down Expand Up @@ -92,7 +94,7 @@ def make_dispatch_inputs(self):
return dispatch_inputs


class OptimizedDispatchController(PyomoControllerBaseClass):
class OptimizedDispatchStorageController(PyomoStorageControllerBaseClass):
"""Operates storage based on optimization to meet the demand profile based on
available commodity from generation profiles and demand profile while minimizing costs.

Expand All @@ -107,7 +109,7 @@ class OptimizedDispatchController(PyomoControllerBaseClass):

def setup(self):
"""Initialize the optimized dispatch controller."""
self.config = OptimizedDispatchControllerConfig.from_dict(
self.config = OptimizedDispatchStorageControllerConfig.from_dict(
merge_shared_inputs(self.options["tech_config"]["model_inputs"], "control")
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


@define(kw_only=True)
class PyomoControllerBaseConfig(BaseConfig):
class PyomoStorageControllerBaseConfig(BaseConfig):
"""
Configuration data container for Pyomo-based storage / dispatch controllers.

Expand Down Expand Up @@ -74,7 +74,7 @@ def __attrs_post_init__(self):
] * self.n_control_window


class PyomoControllerBaseClass(om.ExplicitComponent):
class PyomoStorageControllerBaseClass(om.ExplicitComponent):
_time_step_bounds = (
3600,
3600,
Expand Down
22 changes: 11 additions & 11 deletions h2integrate/control/test/test_heuristic_controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
from h2integrate.storage.battery.pysam_battery import PySAMBatteryPerformanceModel
from h2integrate.storage.storage_performance_model import StoragePerformanceModel
from h2integrate.storage.simple_storage_auto_sizing import StorageAutoSizingModel
from h2integrate.control.control_strategies.heuristic_pyomo_controller import (
HeuristicLoadFollowingController,
)
from h2integrate.control.control_rules.storage.pyomo_storage_rule_baseclass import (
PyomoRuleStorageBaseclass,
)
from h2integrate.control.control_strategies.storage.heuristic_pyomo_controller import (
HeuristicLoadFollowingStorageController,
)


@fixture
Expand Down Expand Up @@ -39,7 +39,7 @@ def tech_config_battery():
"technologies": {
"battery": {
"dispatch_rule_set": {"model": "PyomoRuleStorageBaseclass"},
"control_strategy": {"model": "HeuristicLoadFollowingController"},
"control_strategy": {"model": "HeuristicLoadFollowingStorageController"},
"performance_model": {"model": "PySAMBatteryPerformanceModel"},
"model_inputs": {
"shared_parameters": {
Expand Down Expand Up @@ -97,7 +97,7 @@ def tech_config_generic():
"technologies": {
"h2_storage": {
"dispatch_rule_set": {"model": "PyomoRuleStorageBaseclass"},
"control_strategy": {"model": "HeuristicLoadFollowingController"},
"control_strategy": {"model": "HeuristicLoadFollowingStorageController"},
"performance_model": {"model": "StoragePerformanceModel"},
"model_inputs": {
"shared_parameters": {
Expand Down Expand Up @@ -134,7 +134,7 @@ def tech_config_autosizing():
"technologies": {
"h2_storage": {
"dispatch_rule_set": {"model": "PyomoRuleStorageBaseclass"},
"control_strategy": {"model": "HeuristicLoadFollowingController"},
"control_strategy": {"model": "HeuristicLoadFollowingStorageController"},
"performance_model": {"model": "StorageAutoSizingModel"},
"model_inputs": {
"shared_parameters": {
Expand Down Expand Up @@ -194,7 +194,7 @@ def test_heuristic_load_following_battery_dispatch(

prob.model.add_subsystem(
"battery_heuristic_load_following_controller",
HeuristicLoadFollowingController(
HeuristicLoadFollowingStorageController(
plant_config=plant_config_battery,
tech_config=tech_config_battery["technologies"]["battery"],
),
Expand Down Expand Up @@ -561,7 +561,7 @@ def test_heuristic_load_following_battery_dispatch_change_capacities(

prob.model.add_subsystem(
"battery_heuristic_load_following_controller",
HeuristicLoadFollowingController(
HeuristicLoadFollowingStorageController(
plant_config=plant_config_battery,
tech_config=tech_config_battery["technologies"]["battery"],
),
Expand Down Expand Up @@ -787,7 +787,7 @@ def test_heuristic_load_following_dispatch_with_generic_storage(

prob.model.add_subsystem(
"h2_storage_heuristic_load_following_controller",
HeuristicLoadFollowingController(
HeuristicLoadFollowingStorageController(
plant_config=plant_config_h2_storage,
tech_config=tech_config_generic["technologies"]["h2_storage"],
),
Expand Down Expand Up @@ -935,7 +935,7 @@ def test_heuristic_dispatch_with_autosizing_storage_demand_less_than_avg_in(

prob.model.add_subsystem(
"h2_storage_controller",
HeuristicLoadFollowingController(
HeuristicLoadFollowingStorageController(
plant_config=plant_config_h2_storage,
tech_config=tech_config_autosizing["technologies"]["h2_storage"],
),
Expand Down Expand Up @@ -1021,7 +1021,7 @@ def test_heuristic_dispatch_with_autosizing_storage_demand_is_avg_in(

prob.model.add_subsystem(
"h2_storage_controller",
HeuristicLoadFollowingController(
HeuristicLoadFollowingStorageController(
plant_config=plant_config_h2_storage,
tech_config=tech_config_autosizing["technologies"]["h2_storage"],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

from h2integrate.storage.battery.pysam_battery import PySAMBatteryPerformanceModel
from h2integrate.storage.storage_performance_model import StoragePerformanceModel
from h2integrate.control.control_strategies.heuristic_pyomo_controller import (
HeuristicLoadFollowingController,
)
from h2integrate.control.control_rules.storage.pyomo_storage_rule_baseclass import (
PyomoRuleStorageBaseclass,
)
from h2integrate.control.control_strategies.storage.heuristic_pyomo_controller import (
HeuristicLoadFollowingStorageController,
)
from h2integrate.control.control_strategies.storage.demand_openloop_storage_controller import (
DemandOpenLoopStorageController,
)
Expand Down Expand Up @@ -68,7 +68,7 @@ def make_battery_pyo_group(plant_config_bat):
bat_tech_config = {
"battery": {
"dispatch_rule_set": {"model": "PyomoRuleStorageBaseclass"},
"control_strategy": {"model": "HeuristicLoadFollowingController"},
"control_strategy": {"model": "HeuristicLoadFollowingStorageController"},
"performance_model": {"model": "PySAMBatteryPerformanceModel"},
"model_inputs": {
"shared_parameters": {
Expand Down Expand Up @@ -104,7 +104,7 @@ def make_battery_pyo_group(plant_config_bat):
perf_comp = PySAMBatteryPerformanceModel(
plant_config=plant_config_bat, tech_config=bat_tech_config["battery"]
)
control_comp = HeuristicLoadFollowingController(
control_comp = HeuristicLoadFollowingStorageController(
plant_config=plant_config_bat, tech_config=bat_tech_config["battery"]
)

Expand All @@ -119,7 +119,7 @@ def make_h2_storage_pyo_group(plant_config_h2s):
h2s_tech_config = {
"h2_storage": {
"dispatch_rule_set": {"model": "PyomoRuleStorageBaseclass"},
"control_strategy": {"model": "HeuristicLoadFollowingController"},
"control_strategy": {"model": "HeuristicLoadFollowingStorageController"},
"performance_model": {"model": "StoragePerformanceModel"},
"model_inputs": {
"shared_parameters": {
Expand Down Expand Up @@ -152,7 +152,7 @@ def make_h2_storage_pyo_group(plant_config_h2s):
perf_comp = StoragePerformanceModel(
plant_config=plant_config_h2s, tech_config=h2s_tech_config["h2_storage"]
)
control_comp = HeuristicLoadFollowingController(
control_comp = HeuristicLoadFollowingStorageController(
plant_config=plant_config_h2s, tech_config=h2s_tech_config["h2_storage"]
)

Expand Down
Loading
Loading