Skip to content

Commit e922c52

Browse files
jaredthomas68baycjohnjasaelenya-grantkbrunik
authored
Pyomo dispatch (#211)
* refactor open loop controller classes * update inputs for control model functionality * refactor model processing * pre-commit formatting updates * missing driver_config from refactor * pre-commit formatting fix * adding missing driver_config declaration to open loop controller base class * shift from generic to * correct incorrect comment * new controller directory structure * add *_out/ to .gitignore to avoid clutter * edit change log * demand controller working and tested in single-tech system * add h2 dispatch example * working with pass through * complete h2 dispatch example and corresponding example test * h2 dispatch example plot * add doc strings and other comments/explanations * update docs * rename control_model to control_strategy * update changelog and test_all_examples * update example for h2 rule-based dispatch * add PyXDSM output to .gitignore * rename control_methods to control_strategies * rename * rename * restore openloop_controllers.py from develop * replace old openloop contents with new * remove control_strategies/openloop_controllers.py * move openloop_controllers.py to control_strategies directory * move openloop_controllers.py back to controllers/ * fix typo * revert cost_coeffs.csv changes * update examples for financial group default naming and control naming changes * typing adjustment reverted by hook * Removed time_steps as an input to controllers * minor refactor to demand controller * create base class for Pyomo dispatch rules for individual technologies * Made demand profile available as an OpenMDAO input * Added back persistent variables * add infrastructure for pyomo dispatch * input files for pyomo dispatch test * remove debugging artifacts * remove copy shape from demand profile to allow users to specify the demand profile in the config * revert base class start * enable passing of pyomo objects for pyomo dispatch * add battery baseclass * add initial pysam battery wrapper; note, not fully functional * add heuristic dispatch controller for battery from HOPP * include dispatch rule framework * add heuristic dispatch test * generalize heuristic dispatch and change battery units to kW from MW * update for financial input rework * restructuring control and dispatch folders * split out pyomo comtrol tests * move previously missed pyomo test * wip * move storage pyomo rules to storage rules base class * propogate use of baseclass for pyomo rules to technologies * successfully pass rules * dynamically set pyomo rule names * allow dispatch rules in dispatch tech * pass pyomo_dispatch_solver to storage performance model * reorder so control and dispatch rules are put into tech groups first * updating pysam battery model * add more pseudo code * update pysam battery model * update pyomo controller, separating from openloop controller * WIP: heuristic controller test update * a step to generalize matching dispatch techs group names * update heuristic load following battery dispatch test * generalize the return of pyomo blocks * bring in changes from elenya-grant/dev/battery to allow battery tests to run * add logic for over charging/dischargin and move demand to be an openMDAO input * update test values for new logic and add demand as openMDAO input * updated battery dispatch tests to included min and max SOC tests * Battery cost model and updates to performance model (#3) * added battery cost model and updated pysam battery so capacity is input --------- Co-authored-by: Jared Thomas <jaredthomas68@gmail.com> * run pre-commit hooks back to fc3bbde * precommit adjustments * update heuristic battery dispatch * update h2storage naming * increase grid limit value so it is not a limiting factor * set default value for grid_limit to be high * remove grid limit from test input file * update test for heuristic battery controller * rename test input folder for h2_storage * generalize naming to be technology agnostic * update to get n_timesteps and dt from plant_config * update electricity out from battery to remove charged energy * WIP: example 18; NOTE: mod in h2integrate_model is stand-in for demand module * fix typo Co-authored-by: John Jasa <john.jasa@nrel.gov> * fix typo Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update h2integrate/storage/battery/pysam_battery.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update h2integrate/core/h2integrate_model.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * Reworked setup order in H2I * update pysam battery logic to finally be correct, plus example * updating test and example * WIP: update h2storage to use new heuristic structure * battery control pyomo tests all passing * refactor demand no longer required by performance model * wip: separation of dispatch and simulate * Removed policy_parameters throughout * removed unused tech_config_heuristic in test_controllers * removed cost_year from WindPlantCostModelConfig * removed unused battery baseclasses * removed policy parameters from test_controllers plant configs * wip: fix pysam battery usage * wip: debug p_chargeable * wip: adding local checks * Making pyomo control options a config * Updating after merge * Merging; pre-commit fix * finance fix * correct logic and update tests * swap np.max for np.maximum * Working on testing (#4) * units fix and merge_shared_inputs * Update SOC start value * Update battery power output keys and adjust tolerances * update tests --------- Co-authored-by: Genevieve Starke <genevieve.starke@nrel.gov> * get all tests passing * update example 14 * update names from 'resource' to 'commodity' * add abs_tol for max SOC test * add rtol to max SOC test * adjust tol * adjust tol for unmet demand test * add more checks on how much power the battery can charge or discharge * update tolerance * adjust tol * adjust expected values * rename resource to commodity for dispatch and battery. print warning if unable to generate xdsm diagram rather than raising an error * remove internal battery sizing method in favor of using the builtin one from PySAM. * remove commented code * update comments and doc strings based on feedback * update doc strings and validators * add test for example 18 * remove code from usage: pyomo [-h] [--version] {build-extensions,convert,download-extensions,help,install-extras,model-viewer,run,solve,test-solvers} ... This is the main driver for the Pyomo optimization software. options: -h, --help show this help message and exit --version show program's version number and exit subcommands: {build-extensions,convert,download-extensions,help,install-extras,model-viewer,run,solve,test-solvers} build-extensions Build compiled extension modules convert Convert a Pyomo model to another format download-extensions Download compiled extension modules help Print help information. install-extras Install "extra" packages that Pyomo can leverage. model-viewer Run the Pyomo model viewer run Execute a command from the Pyomo bin (or Scripts) directory. solve Optimize a model test-solvers Test Pyomo solvers ------------------------------------------------------------------------- Pyomo supports a variety of modeling and optimization capabilities, which are executed either as subcommands of 'pyomo' or as separate commands. Use the 'help' subcommand to get information about the capabilities installed with Pyomo. Additionally, each subcommand supports independent command-line options. Use the -h option to print details for a subcommand. For example, type pyomo solve -h to print information about the `solve` subcommand. branch that will be saved for the pr later * fix example 14 plant input * remove changes that have been saved in for later pr * roll back h2 pyomo dispatch - save for later in 'pyomo_h2' for another pr * pull dt and n_timesteps from plant_config * move h2 pyomo test inputs out of pyomo and into pyomo_h2 for a later pr * move input_power from being a discrete_input for openmdao to being in the input yaml and config * make names in battery and control more explicit * create pysam battery with pyomo heuristic system test * include generic converter rules * change 'excess' to 'unused' in accordance with naming discussion * remove h2 storage rules * shift to generic dispatch for pyomo with storage techs * adjust test from battery dispatch rules to generic dispatch rules * update modify_tech_config function to run model.setup() internally by default, with the option to not run model.setup() * change location for example 18 (wind battery dispatch) to match example 19 (simple dispatch) to avoid saving more resource files in git * remove TODOs that are not needed in this PR anymore. * update doc strings * generalize pyomo storage rules * remove comments specific to pyomo_opt * edit doc string * include notebook version of example 18 * remove notebook version * add control framework documentation * repair errors arising due to renaming * update changelog * rename test, rename example 18 input yaml * unify unit specifications to rates and unify names between all techs * update resource_name to commodity_name, resource_units to commodity_units, and kg to kg/h * revert switch from excess_acid to unused_acid * update docs after bringing in commodity stream PR (#294) * update links in control docs * update doc strings to clarify what is included in commodity_out for storage and control * correct naming for h2 storage input for electrolyzer rating * change from battery_electricity_out to battery_electricity_discharge and add some test cleanup * correct naming typo and add pyomo comment in docs * Update docs/control/control_overview.md Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update docs/technology_models/pysam_battery.md Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update docs/technology_models/pysam_battery.md Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update examples/18_pyomo_heuristic_dispatch/18_run_pyomo_heuristic_dispatch.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update examples/18_pyomo_heuristic_dispatch/18_run_pyomo_heuristic_dispatch.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * put error in place for compute method of PyomoRuleBaseClass * remove incorrect error raising and correct comment * change from _demand_in to _demand * rename run script for example 18 * add comments * Update h2integrate/storage/battery/battery_baseclass.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update h2integrate/storage/battery/battery_baseclass.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * update pysam battery call without controller to have a pseudo control option * Update h2integrate/storage/battery/pysam_battery.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * Update h2integrate/storage/battery/pysam_battery.py Co-authored-by: John Jasa <john.jasa@nrel.gov> * remove finance parameters because they are unused - we are only testing control and battery outputs here * update docs * Update h2integrate/storage/battery/battery_baseclass.py Co-authored-by: kbrunik <102193481+kbrunik@users.noreply.github.com> * Update h2integrate/control/control_rules/converters/generic_converter.py Co-authored-by: kbrunik <102193481+kbrunik@users.noreply.github.com> * move battery tests to battery directory * open loop html * Apply suggested doc updates from code review Co-authored-by: kbrunik <102193481+kbrunik@users.noreply.github.com> * updating formatting to fix tests * fixing formatting for pre-commit hooks * fixing formatting from including suggestions from code reivew * more pre-commit fixes * add error message if provided tech_name does not match the actual tech name * Consolidated pyomo controller test files * include file for testing that was left out * include file for testing that was left out * update docs to clarify system_commodity_interface_limit * update min/max storage fraction handling to use provided limits * remove unused battery themal function (it is in PySAM BatteryTools) --------- Co-authored-by: bayc <christopher.j.bay@gmail.com> Co-authored-by: John Jasa <johnjasa11@gmail.com> Co-authored-by: elenya-grant <116225007+elenya-grant@users.noreply.github.com> Co-authored-by: Chris Bay <12664940+bayc@users.noreply.github.com> Co-authored-by: John Jasa <john.jasa@nrel.gov> Co-authored-by: kbrunik <kbrunik@gmail.com> Co-authored-by: kbrunik <102193481+kbrunik@users.noreply.github.com> Co-authored-by: Genevieve Starke <genevieve.starke@nrel.gov>
1 parent 7550089 commit e922c52

65 files changed

Lines changed: 33271 additions & 391 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
- Added an optimized offshore methanol production case to examples/03_methanol/co2_hydrogenation_doc
77
- Updated setting up recorder in `PoseOptimization`
88
- Added resource models to make solar resource API calls to the NREL Developer GOES dataset
9+
- Added framework to run heuristic load following dispatch for storage technologies
10+
- Added PySAM battery model as a storage technology performance model
911
- Added `create_om_reports` option to driver config to enable/disable OpenMDAO reports (N2 diagrams, etc.)
1012

1113
## 0.4.0 [October 1, 2025]

docs/_toc.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ parts:
3838
- file: technology_models/simple_generic_storage.md
3939
- file: technology_models/methanol.md
4040
- file: technology_models/ammonia.md
41+
- file: technology_models/pysam_battery.md
4142

4243
- caption: Resource Models
4344
chapters:
@@ -48,6 +49,14 @@ parts:
4849
- file: resource/solar_index
4950
- file: resource/goes_solar_v4_api
5051

52+
- caption: Control
53+
chapters:
54+
- file: control/control_overview.md
55+
56+
- caption: Examples
57+
chapters:
58+
- file: examples/01-green-hydrogen
59+
5160
- caption: Developer Guide
5261
chapters:
5362
- file: CONTRIBUTING

docs/control/control_overview.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Control Overview
2+
3+
There are two different systematic approaches, or frameworks, in H2Integrate for control: [open-loop](open-loop-control) and [pyomo](pyomo-control). These two frameworks are useful in different situations and have different impacts on the system and control strategies that can be implemented. Both control frameworks are focused on dispatching storage technologies and as such can currently only be used on storage technologies. However, we plan to extend them to work more generally as system controllers, and even though the controllers must be placed on storage technologies for now, they behave somewhat like system controllers in that they may curtail/discard commodity amounts exceeding the needs of the storage technology and the specified demand. However, any unused commodity may be connected to another down-stream component to avoid actual curtailment.
4+
5+
(open-loop-control)=
6+
## Open-loop control framework
7+
The first approach, open-loop control, assumes no feedback of any kind to the controller. The open-loop framework does not require a detailed performance model and can essentially act as the performance model in the absence of a dedicated performance model for a given storage technology. The open-loop framework establishes a control component that runs the control and passes out information about storage dispatch, state of charge (SOC), etc.
8+
9+
An example of an N2 diagram for a system using the open-loop control framework for hydrogen storage and dispatch is shown below ([click here for an interactive version](./figures/open-loop-n2.html)). Note that the hydrogen out going into the finance model is coming from the control component.
10+
11+
![](./figures/open-loop-n2.png)
12+
13+
The open-loop framework currently supports only two control strategy, `pass_through_controller`, and `demand_open_loop_controller`. The `pass_through_controller` simply directly passes the input commodity flow to the output without any modifications. It is useful for testing, as a placeholder for more complex controllers, and for maintaining consistency between controlled and uncontrolled frameworks as this 'controller' does not alter the system output in any way. The `demand_open_loop_controller` uses simple logic to dispatch the storage technology when demand is higher than commodity generation and charges the storage technology when the commodity generation exceeds demand, both cases depending on the storage technology's state of charge. For the `demand_open_loop_controller`, the storage state of charge is an estimate in the control logic and is not informed in any way by the storage technology performance model.
14+
15+
For examples of how to use the open-loop control framework, see the following:
16+
- For the `pass_through_controller`
17+
- `examples/01_onshore_steel_mn`
18+
- `examples/02_texas_ammonia`
19+
- `examples/12_ammonia_synloop`
20+
- For the `demand_open_loop_controller`
21+
- `examples/14_wind_hydrogen_dispatch/`
22+
- `examples/19_simple_dispatch/`
23+
24+
(pyomo-control)=
25+
## Pyomo control framework
26+
[Pyomo](https://www.pyomo.org/about) is an open-source optimization software package. It is used in H2Integrate to facilitate modeling and solving control problems, specifically to determine optimal dispatch strategies for dispatchable technologies.
27+
28+
The second systematic control approach, pyomo control, allows for the possibility of feedback control at specified intervals, but can also be used for open-loop control if desired. 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.
29+
30+
An example of an N2 diagram for a system using the pyomo control framework for hydrogen storage and dispatch is shown below ([click here for an interactive version](./figures/pyomo-n2.html)). Note the control rules being passed to the dispatch component and the dispatch function, containing the full pyomo model, being passed to the performance model for the battery/storage technology. Another important thing to recognize, in contrast to the open-loop control framework, is that the storage technology outputs (commodity out, SOC, unused commodity, etc) are passed out of the performance model when using the Pyomo control framework rather than from the control component.
31+
32+
![](./figures/pyomo-n2.png)
33+
34+
The pyomo control framework currently supports only a simple heuristic method, `heuristic_load_following_controller`, but we plan to extend the framework to be able to run a full dispatch optimization using a pyomo solver. 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 `pyomo_dispatch_generic_converter` for generating technologies, and `pyomo_dispatch_generic_storage` for storage technologies. More complex rule sets may be developed as needed.
35+
36+
For an example of how to use the pyomo control framework with the `heuristic_load_following_controller`, see
37+
- `examples/18_pyomo_heuristic_wind_battery_dispatch`

0 commit comments

Comments
 (0)