Skip to content

Reliability Prototype - #833

Draft
RHammond2 wants to merge 29 commits into
NatLabRockies:developfrom
RHammond2:feature/reliability
Draft

Reliability Prototype#833
RHammond2 wants to merge 29 commits into
NatLabRockies:developfrom
RHammond2:feature/reliability

Conversation

@RHammond2

@RHammond2 RHammond2 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Integration of Basic Reliability Modeling

This is an early stage (non-working) prototype of a Weibull-based reliability model for the NaturalGasPerformanceModel.

For now, the model is designed to slot into any performance model using an hourly timestep over a single year. The key output is an array of availability (0 for downtime and 1 for operational) that is multiplied by the demand array.

Working example

from h2integrate.reliability import models

reliability_config = {
    "failure_model": "WeibullReliability",
    "maintenance_model": "FixedIntervalReliability",
    "failure_parameters": {
        "scale": 0.5,
        "shape": 1,
        "burn_in": 3.33,
        "n_components": 2,  # note: can also use a list of scale/shape values, this is just convenient when identical
        "downtime": {
            "model": "FixedDowntime",
            "hours": 5,
            "n_components": 2,
        },
    },
    "maintenance_parameters":{
        "frequency": [0.25, 1, 4],
        "downtime": {
            "model": "LogNormalDowntime",
            "mean": 2,
            "sigma": 1,
            "n_components": 3,
        },
    },
}

# we can also do the same thing for maintenance, the whole operation just hasn't been combined yet
failure = models.create_failure_model(reliability_config)

# energy-based availability without ramping of downtime events...yet
print(f"System-level availability (min of all components): {failure.system_availability.sum() / failure.system_availability.size:.4%}")

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 8: New Model Checklist (if applicable)

TODO: (see other feedback/considerations for what I'm considering or other aspects I could be missing)

  • Get the model working
  • Burn in period (skipping forward x number of years) - suggestion from @cfrontin
  • Componentizable approach (matrix of failures vs single model)
  • Maintenance (fixed interval) and Failures (random)
    • Integrate failure and maintenance into overarching system availability
  • Enable randomized downtime
  • Tests
  • Better docs
  • Rethink approach to base models
  • Remove setup steps from individual models for easy addition of new models
  • Ramping up/down production from 0-1/1-0
  • create array gt/ge validators outside of class
  • n_timesteps as an input to the model in place of using module level N_TIMESTEPS = 8760.
  • dt as an input to the model for duration of the simulation in place of N_TIMESTEPS = 8760.
  • allow user to input use_reliability for a performance model to toggle its usage or check that a model has been provided if using during model initialization.

Type of Reviewer Feedback Requested (on Draft PR)

Structural feedback: Anything is welcome

Implementation feedback: Should the reliability slot into the performance in a more streamlined way? Any other feedback is welcome.

Other feedback/considerations for the finalized PR: It would be great to get feedback on the importance of the following items and any preferred approaches.

  • better control over random seeding - kick the can way down the road
  • uncertainty quantification - getting well ahead of ourselves
  • ramping before/after downtime events
  • passing n_timesteps from the plant configuration
  • Calculate availability at initialization or manually run model.calculate_availability()?

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

Section 5: Impacted Areas of the Software

Section 5.1: New Files

  • path/to/file.extension
    • method1: What and why something was changed in one sentence or less.

Section 5.2: Modified Files

  • path/to/file.extension
    • method1: What and why something was changed in one sentence or less.

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
    • Add the new model to the appropriate __init__.py file to ensure it is properly imported and used in supported_models.py
    • 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
elenya-grant self-requested a review August 11, 2026 19:49
Comment thread h2integrate/reliability/models.py Outdated

@elenya-grant elenya-grant 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.

Left some big-picture comments! Happy to chat through anything if you'd like! Thanks!

Comment thread h2integrate/reliability/models.py Outdated
shape: float = field(validator=validators.instance_of(float))
downtime: Any = field(converter=generate_downtime_model)
downtime_per_event: np.ndarray = field(init=False, validator=validators.instance_of(np.ndarray))
availability: np.ndarray = field(

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.

could we make n_timesteps a configuration parameter? Then we could have availability be initialized in __attrs_post_init__ as np.ones(n_timesteps)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The generation of availability is now done in calculate_availability to make it easier to automate, and adding the n_timesteps to the to do section.

Comment thread h2integrate/reliability/models.py Outdated
frequency: float = field(validator=(validators.instance_of((float, int)), validators.gt(0)))
downtime: Any = field(converter=generate_downtime_model)
downtime_per_event: np.ndarray = field(init=False, validator=validators.instance_of(np.ndarray))
availability: np.ndarray = field(

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.

same comment here about having n_timesteps as a configuration parameter.

Comment thread h2integrate/reliability/models.py Outdated
Comment on lines +177 to +178
interval = np.ceil(8760 / frequency).astype(int)
first_occurrence = rng.integers(0, np.where(interval > 8760, 8760, interval))

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.

should these 8760's be n_timesteps?

Comment thread h2integrate/reliability/models.py Outdated
)
# TODO: handle start > 8760
end = start + duration
end = np.where(end > 8760, 8760, end)

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.

same here - should 8760 be n_timesteps or N_TIMESTEPS (as you have it now?)

to a quarterly downtime event and 0.25 is equivalent to an every 4 years downtime event.
For all events the timing of the first event will be sampled within the first year or
interval period to offset events from being based on January 1st in an 8760.
downtime (int | float | dict): Either fixed length of each downtime, in hours, or a

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.

could we name this downtime_hrs or something? Also - can these models be updated to handle varying timesteps? It seems like a lot of logic is intended for hourly? If so - I think we should should make dt an input parameter too.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This could be tricky, but I'll add it to the to do section.

merge_shared_inputs(self.options["tech_config"]["model_inputs"], "performance"),
additional_cls_name=self.__class__.__name__,
)
if self.options["tech_config"]["model_inputs"]["reliability"]:

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.

do we need to use self.options["tech_config"]["model_inputs"].get("reliability", False) here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not exactly, but that did get me thinking on a better way to use use_reliability, so I appreciate the question!

Comment on lines +71 to +72
self.reliability_model = None
self.use_reliability = False

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.

Could these be parameters in the NaturalGasPerformanceConfig? So a user can input reliability_model and use_reliability? Where the __attrs_post_init__ checks that reliability_model is provided if use_reliability is True?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

That's a good question, it didn't dawn on me that a user could want to provide a definition, but not use it. Though it could be easier to iterate on a problem by simply turning it on/off instead of commenting out a whole section of the inputs. I'll also add this to the to do section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants