Skip to content

System level control framework#751

Merged
johnjasa merged 173 commits into
developfrom
system_level_control
Jun 15, 2026
Merged

System level control framework#751
johnjasa merged 173 commits into
developfrom
system_level_control

Conversation

@elenya-grant

@elenya-grant elenya-grant commented May 12, 2026

Copy link
Copy Markdown
Collaborator

System level control framework

This work was also done by @kbrunik and @johnjasa :)

Introducing the initial framework for system level control. This PR introduces 3 system level controllers, which are simple controllers. The goal of this PR is to introduce the framework for system level control - which will be further developed in future PRs that address the issues listed in Section 4.

The three system level controllers are:

  • DemandFollowingControl
  • CostMinimizationControl
  • ProfitMaximizationControl

Many of the file changes in this PR are related to adding control classifiers for each technology performance model.

PR's that were pre-requisites to this are:

The information that the system level controller is input for each technology is:

  • the rate

Section 1: Type of Contribution

  • Feature Enhancement
    • Framework
    • New Model
    • Updated Model
    • Tools/Utilities
    • Other (please describe):
  • Bug Fix
  • Documentation Update
  • CI Changes
  • Other (please describe):

Section 2: Draft PR Checklist

  • Open draft PR
  • Describe the feature that will be added
  • Fill out TODO list steps
  • Describe requested feedback from reviewers on draft PR
  • Complete Section 7: New Model Checklist (if applicable)

TODO:

  • Step 1
  • Step 2

Type of Reviewer Feedback Requested (on Draft PR)

Structural feedback:

Implementation feedback:

Other feedback:

Section 3: General PR Checklist

  • PR description thoroughly describes the new feature, bug fix, etc.
  • Added tests for new functionality or bug fixes
  • Tests pass (If not, and this is expected, please elaborate in the Section 6: Test Results)
  • Documentation
    • Docstrings are up-to-date
    • Related docs/ files are up-to-date, or added when necessary
    • Documentation has been rebuilt successfully
    • Examples have been updated (if applicable)
  • CHANGELOG.md
    • At least one complete sentence has been provided to describe the changes made in this PR
    • After the above, a hyperlink has been provided to the PR using the following format:
      "A complete thought. [PR XYZ]((https://github.com/NatLabRockies/H2Integrate/pull/XYZ)", where
      XYZ should be replaced with the actual number.

Section 4: Related Issues

Issues related to this PR

  • Discussing technology classifications Issue #687

Issues for planned follow-on work

  • Require user to specify demand component in control_parameters (Issue #739)​
  • Only connect technologies upstream of the demand technology to the SLC (Issue #740)​
  • Add methods to baseclass to improve handling of multi-commodity systems (Issue #741)​
  • Handling of splitters (Issue #747)​
  • Custom control strategies (Issue #748)​

Section 5: Impacted Areas of the Software

Section 5.1: New Files

  • h2integrate/control/control_strategies/system_level/solver_options.py
    • SLCSolverOptionsConfig: configuration class for the non-linear solver options to specify for the system level controller. This is used to avoid usage of hard-coded defaults in H2IntegrateModel.
  • h2integrate/control/control_strategies/system_level/system_level_control_base.py
    • SystemLevelControlBase: baseclass for system level controllers. Includes methods to setup inputs and outputs and methods that may be useful for the controllers. The setup() method ensures that all commodity streams are defined with consistent units (aka - all hydrogen commodity streams are defined in kg/h and all electricity commodity streams are defined in kW, etc)
  • h2integrate/control/control_strategies/system_level/cost_minimization_control.py
    • CostMinimizationControl:
  • h2integrate/control/control_strategies/system_level/demand_following_control.py
    • DemandFollowingControl:
  • h2integrate/control/control_strategies/system_level/profit_maximization_control.py
    • ProfitMaximizationControl:
    • ProfitMaximizationControlConfig

Section 5.2: Modified Files (of importance)

  • h2integrate/core/h2integrate_model.py
    • __init__(): Added attribute slc which is used to decide whether to call _classify_slc_technologies() and add_system_level_controller.
    • _classify_slc_technologies(): new method that creates the slc_config dictionary used in the system level controller base class and is an input to add_system_level_controller()
    • add_system_level_controller(): new method that creates the system level control model and connects the corresponding inputs and outputs between technologies and the system level controller
    • create_technology_models(): updated to populate the attribute self.tech_control_classifiers which is a dictionary with keys as the technology names and values of the corresponding technology control classifier.
  • h2integrate/core/supported_models.py: added strategy_map dictionary which is the equivalent of supported_models but specifically for system level controllers
  • h2integrate/core/model_baseclasses.py
    • PerformanceModelBaseClass
      • apply_curtailment(): new method that applies curtailment to the output of any technology that is classified as "flexible". This logic only happens if "system_level_control" is found as a top-level key in the plant configuration file.
      • setup(): checks if control classifier is flexible and if so, adds input of f"{self.commodity}_set_point" and output of f"uncurtailed_{self.commodity}_out"
    • CostModelBaseClass
      • setup(): added output of "marginal_cost".
  • h2integrate/finances/profast_lco.py
    • ProFastLCO.compute(): updated to not run profast if the capacity factor is zero and if system_level_control is found in the plant config. Warns the user that its setting the LCO output to a large number but that it was not actually calculated if the the capacity factor is zero and system_level_control is found in the plant config

Section 6: Additional Supporting Information

Section 7: Test Results, if applicable

Section 8 (Optional): New Model Checklist

  • Model Structure:
    • Follows established naming conventions outlined in docs/developer_guide/coding_guidelines.md
    • Used attrs class to define the Config to load in attributes for the model
      • If applicable: inherit from BaseConfig or CostModelBaseConfig
    • Added: initialize() method, setup() method, compute() method
      • If applicable: inherit from CostModelBaseClass
  • Integration: Model has been properly integrated into H2Integrate
    • Added to supported_models.py
    • If a new commodity_type is added, update create_financial_model in h2integrate_model.py
  • Tests: Unit tests have been added for the new model
    • Pytest-style unit tests
    • Unit tests are in a "test" folder within the folder a new model was added to
    • If applicable add integration tests
  • Example: If applicable, a working example demonstrating the new model has been created
    • Input file comments
    • Run file comments
    • Example has been tested and runs successfully in test_all_examples.py
  • Documentation:
    • Write docstrings using the Google style
    • Model added to the main models list in docs/user_guide/model_overview.md
      • Model documentation page added to the appropriate docs/ section
      • <model_name>.md is added to the _toc.yml
    • Run generate_class_hierarchy.py to update the class hierarchy diagram in docs/developer_guide/class_structure.md

elenya-grant and others added 30 commits April 9, 2026 12:50
Draft implementation of separate curtailment model
@johnjasa johnjasa marked this pull request as ready for review June 10, 2026 15:06
@johnjasa johnjasa marked this pull request as draft June 10, 2026 15:46
@johnjasa johnjasa marked this pull request as ready for review June 10, 2026 15:46
@johnjasa johnjasa marked this pull request as draft June 10, 2026 16:28
@johnjasa johnjasa marked this pull request as ready for review June 10, 2026 16:29
@johnjasa johnjasa marked this pull request as draft June 10, 2026 17:01
@johnjasa johnjasa marked this pull request as ready for review June 10, 2026 17:01
@johnjasa johnjasa marked this pull request as draft June 10, 2026 18:17
@johnjasa johnjasa marked this pull request as ready for review June 10, 2026 18:18

@vijay092 vijay092 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice work everyone! I mostly had some clarifying questions to make sure I understand things correctly.

System-level control (SLC) within H2I is meant to operate to control the entire plant with performance and cost feedback driving the operation of the plant or system in a closed-loop. It acts as a supervisory controller meaning that it can work to coordinate the entire system and can work with other technology level controllers.

```{note}
The SLC framework is *technology-agnostic* and works with any H2I technology (converters, storage, feedstocks, demand components, etc.). It only cares about a technology's [`_control_classifier`](control_classifier.md) and the commodity it produces. To opt a technology in, set `_control_classifier` on its performance model; for `flexible` models, also call `self.apply_curtailment(outputs)` at the end of `compute()`. See the [developer guide on adding a new technology](../../developer_guide/adding_a_new_technology.md) for the full checklist.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, what does flexible mean here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flexible means that the model outputs can be curtailed but otherwise cannot responded to a set point. The control classifiers are specific to the model as implemented in H2I so in reality a wind farm can respond to set points to adjust the turbines to better capture the wind, in H2I the pysam model will not change based on a setpoint received and the outputs of the wind farm simulation could be curtailed but that's it. Happy to chat more about this if that would be helpful. The classifiers were a big piece of discussion so it's certainly a bit confusing since they don't fully match with intuition.

Comment thread docs/control/system_level_control/system_level_control.md Outdated
Comment thread docs/control/system_level_control/system_level_control.md
Comment thread docs/control/system_level_control/slc_profit_max.md
Comment thread docs/control/system_level_control/slc_cost_min.md Outdated
Comment thread docs/control/system_level_control/slc_cost_min.md
@johnjasa johnjasa self-requested a review June 11, 2026 01:36
@johnjasa johnjasa requested a review from kbrunik June 11, 2026 17:45
@johnjasa johnjasa requested review from johnjasa and removed request for johnjasa June 11, 2026 17:48
@johnjasa johnjasa dismissed jaredthomas68’s stale review June 15, 2026 20:58

Dismissing as we've discussed Jared's view in standups; can do further mods on this code as needed in the future

@johnjasa johnjasa merged commit 395ab33 into develop Jun 15, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants