From 74bc287ab9bbeb94243124828e88e7828664b10e Mon Sep 17 00:00:00 2001 From: John Jasa Date: Wed, 18 Feb 2026 19:28:19 -0700 Subject: [PATCH 1/2] Added to readme, bumped min python version and CI versions --- .github/workflows/ci.yml | 2 +- README.md | 160 +++++++++++++++++++++++++++++++++------ docs/installing.md | 4 +- docs/intro.md | 4 +- pyproject.toml | 10 +-- 5 files changed, 147 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d8fe66..e774c31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11"] + python-version: ["3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index ec3e4d1..02ac5f8 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,151 @@ -============ -Electrolyzer -============ +# Electrolyzer +[![CI Status](https://github.com/NREL/electrolyzer/actions/workflows/ci.yml/badge.svg)](https://github.com/NREL/electrolyzer/actions/workflows/ci.yml) +[![Lint](https://github.com/NREL/electrolyzer/actions/workflows/black.yml/badge.svg)](https://github.com/NREL/electrolyzer/actions/workflows/black.yml) -.. image:: https://github.com/NREL/electrolyzer/actions/workflows/ci.yml/badge.svg - :target: https://github.com/NREL/electrolyzer/actions/workflows/ci.yml - :alt: CI Status +Electrolyzer is a controls-oriented engineering model for hydrogen production systems. It simulates +multi-stack electrolyzer operation, supports PEM and alkaline cell models, tracks degradation, and +includes levelized cost of hydrogen (LCOH) analysis utilities. -.. image:: https://github.com/NREL/electrolyzer/actions/workflows/black.yml/badge.svg - :target: https://github.com/NREL/electrolyzer/actions/workflows/black.yml - :alt: Lint +## What this repo provides -Electrolyzer contains performance and cost modeling of H2 production. +- Time-series simulation of one or more stacks with supervisory control logic. +- PEM and alkaline electrochemical cell models with polarization curve fitting. +- Degradation tracking (steady, fatigue, and on/off cycling) with optional penalty modes. +- Cost and LCOH analysis tools tied to simulation outputs. +- YAML-based modeling configuration with a JSON schema for validation and defaults. +## Project structure -* Free software: Apache Software License 2.0 +- Core simulation: [electrolyzer/simulation](electrolyzer/simulation) +- Cell models: [electrolyzer/simulation/cell_models](electrolyzer/simulation/cell_models) +- Validation/schema: [electrolyzer/tools/validation.py](electrolyzer/tools/validation.py), [electrolyzer/tools/modeling_schema.yaml](electrolyzer/tools/modeling_schema.yaml) +- LCOH analysis: [electrolyzer/tools/analysis](electrolyzer/tools/analysis) +- Examples: [examples](examples) +- Documentation: [docs](docs) -Quick Installation ------------- +## Installation -``pip install git+https://github.com/NREL/electrolyzer.git`` +Python 3.11+ is required. -For further installation instructions, see the `installing.md` file in the docs folder. +```bash +pip install . +``` -Features --------- +Optional extras: -* TODO +```bash +pip install ".[examples]" # notebooks + example dependencies +pip install -e ".[develop]" # dev + docs tooling +pip install -e ".[all]" # everything +``` -Credits -------- +More detail is in [docs/installing.md](docs/installing.md). -This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template. +## Quick start -.. _Cookiecutter: https://github.com/audreyr/cookiecutter -.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage +Run a simulation from a YAML configuration and a power signal: + +```python +import numpy as np + +from electrolyzer.simulation.bert import run_electrolyzer + +power_signal = np.ones(3600) * 1e6 # 1 MW for 1 hour, in Watts +elec_sys, results = run_electrolyzer("examples/example_02_electrolyzer/modeling_options.yaml", power_signal) + +print(results.head()) +``` + +Compute LCOH using the same signal: + +```python +import numpy as np + +from electrolyzer.tools.analysis.run_lcoh import run_lcoh + +power_signal = np.ones(3600) * 1e6 +lcoe = 0.04418 # $/kWh + +lcoh_breakdown, lcoh_value = run_lcoh( + "examples/example_04_lcoh/cost_modeling_options.yaml", + power_signal, + lcoe, +) + +print(lcoh_value) +``` + +## Modeling configuration + +Models are configured with YAML files validated against a JSON schema. The schema defines defaults +and accepted ranges for parameters like stack rating, cell geometry, degradation rates, and control +policy settings. + +- Schema: [electrolyzer/tools/modeling_schema.yaml](electrolyzer/tools/modeling_schema.yaml) +- Example PEM configuration: [examples/example_02_electrolyzer/modeling_options.yaml](examples/example_02_electrolyzer/modeling_options.yaml) +- Example alkaline configuration: [examples/example_06_alkaline/default_alkaline.yaml](examples/example_06_alkaline/default_alkaline.yaml) + +Key configuration blocks: + +- `electrolyzer.supervisor`: system rating and number of stacks. +- `electrolyzer.controller`: control strategy and decision policy flags. +- `electrolyzer.stack`: stack sizing, cell type, and operational settings. +- `electrolyzer.degradation`: degradation rates and end-of-life parameters. +- `electrolyzer.cell_params`: PEM or alkaline cell model parameters. +- `electrolyzer.costs`: LCOH input data for capex, opex, feedstock, and finance. + +## Control strategies + +The supervisor supports multiple control modes for stack scheduling and power distribution: + +- `PowerSharingRotation`, `SequentialRotation` +- `EvenSplitEagerDeg`, `EvenSplitHesitantDeg` +- `SequentialEvenWearDeg`, `SequentialSingleWearDeg` +- `BaselineDeg` +- `DecisionControl` (composed from policy flags in the YAML) + +See [electrolyzer/simulation/supervisor.py](electrolyzer/simulation/supervisor.py) for logic. + +## Degradation modeling + +Each stack tracks voltage degradation from steady operation, fatigue, and on/off cycling. You can +choose whether degradation penalizes hydrogen production or increases power draw. The end-of-life +voltage delta drives replacement calculations in the LCOH workflow. + +## Outputs + +`run_electrolyzer` returns a supervisor object and a `pandas.DataFrame` of time-series results. +The frame includes overall power and curtailment plus per-stack columns for degradation, cycles, +uptime, hydrogen production rate, and current density. + +## Examples + +- Basic simulation: [examples/example_02_electrolyzer/example_run.py](examples/example_02_electrolyzer/example_run.py) +- Polarization curve fitting: [examples/example_01_polarization/example_run.py](examples/example_01_polarization/example_run.py) +- Controller behavior: [examples/example_05_controller/example_05_controller_options.py](examples/example_05_controller/example_05_controller_options.py) +- Alkaline configuration: [examples/example_06_alkaline/alkaline_example_run.py](examples/example_06_alkaline/alkaline_example_run.py) +- LCOH calculation: [examples/example_04_lcoh/cost_example_run.py](examples/example_04_lcoh/cost_example_run.py) + +## Documentation + +Docs are in [docs](docs). The landing page is [docs/intro.md](docs/intro.md). If you build the +Jupyter Book locally, the generated site lands in [docs/_build/html](docs/_build/html). + +## Testing + +```bash +pytest +``` + +## Contributing + +See [CONTRIBUTING.rst](CONTRIBUTING.rst) and [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md). + +## Citation + +If you use this work in academic research, please cite [CITATION.cff](CITATION.cff). + +## License + +Apache Software License 2.0. See [LICENSE](LICENSE). diff --git a/docs/installing.md b/docs/installing.md index f148ea1..df436cc 100644 --- a/docs/installing.md +++ b/docs/installing.md @@ -16,11 +16,11 @@ For most use cases, installing from source will be the preferred installation ro cd electrolyzer ``` -3. Create a new virtual environment and change to it. Using Conda Python 3.11 (choose your favorite +3. Create a new virtual environment and change to it. Using Conda Python 3.13 (choose your favorite supported version) and naming it 'electrolyzer_env' (choose your desired name): ```bash - conda create --name electrolyzer_env python=3.11 -y + conda create --name electrolyzer_env python=3.13 -y conda activate electrolyzer_env ``` diff --git a/docs/intro.md b/docs/intro.md index 38ac968..54577a6 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -1,7 +1,7 @@ # Welcome to the Electrolyzer Documentation -This repo contains electrolyzer models for use in techno-economic analysis of hydrogen production systems. -The models are designed to be used in conjunction with the [HOPP](https://github.com/NREL/HOPP) and [H2Integrate (formerly GreenHEART)](https://github.com/NREL/greenheart) models developed by the National Renewable Energy Laboratory (NREL). +This repo contains electrolyzer models for use in technoeconomic analysis of hydrogen production systems. +The models are designed to be used in conjunction with the [H2Integrate](https://github.com/NatLabRockies/H2Integrate) tools developed by the National Laboratory of the Rockies. ```{tableofcontents} ``` diff --git a/pyproject.toml b/pyproject.toml index dab7c1d..5ecffd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,10 +6,10 @@ build-backend = "setuptools.build_meta" [project] name = "electrolyzer" dynamic = ["version"] -authors = [{name = "NREL", email = "christopher.bay@nrel.gov"}] +authors = [{name = "NLR", email = "christopher.bay@nlr.gov"}] readme = {file = "README.md", content-type = "text/markdown"} description = "A controls-oriented engineering electrolyzer model." -requires-python = ">=3.9, <3.12" +requires-python = ">=3.11" license = {file = "LICENSE"} dependencies = [ "numpy", @@ -32,9 +32,9 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] [project.optional-dependencies] From e1fb95b17693cf113c0d70a2906f6fdc0a5dacff Mon Sep 17 00:00:00 2001 From: John Jasa Date: Wed, 18 Feb 2026 19:35:49 -0700 Subject: [PATCH 2/2] Removed lint check --- .github/workflows/black.yml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .github/workflows/black.yml diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml deleted file mode 100644 index b04fb15..0000000 --- a/.github/workflows/black.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: Lint - -on: [push, pull_request] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: psf/black@stable