Metadata-Version: 2.4
Name: OpenPinch
Version: 0.6.5
Summary: An advanced pinch analysis and total site integration toolkit
Project-URL: Homepage, https://github.com/waikato-ahuora-smart-energy-systems/OpenPinch
Project-URL: Issues, https://github.com/waikato-ahuora-smart-energy-systems/OpenPinch/issues
Author-email: Tim Walmsley <tim.walmsley@waikato.ac.nz>
License-Expression: MIT
License-File: LICENSE
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.14.2
Requires-Dist: coolprop>=8
Requires-Dist: numpy<3
Requires-Dist: pandas<3
Requires-Dist: pint<1
Requires-Dist: pydantic<3
Requires-Dist: scipy<2
Provides-Extra: brayton-cycle
Requires-Dist: tespy>=0.10.1.post2; extra == 'brayton-cycle'
Provides-Extra: dashboard
Requires-Dist: openpyxl; extra == 'dashboard'
Requires-Dist: plotly; extra == 'dashboard'
Requires-Dist: pyxlsb; extra == 'dashboard'
Requires-Dist: streamlit; extra == 'dashboard'
Provides-Extra: full
Requires-Dist: gekko>=1.3.2; extra == 'full'
Requires-Dist: idaes-pse>=2.11.0; extra == 'full'
Requires-Dist: ipykernel>=7.2.0; extra == 'full'
Requires-Dist: kaleido>=1.3.0; extra == 'full'
Requires-Dist: nbformat>=5.10.4; extra == 'full'
Requires-Dist: openpyxl>=3.1.5; extra == 'full'
Requires-Dist: plotly>=6.8.0; extra == 'full'
Requires-Dist: pyomo>=6.10.0; extra == 'full'
Requires-Dist: pyxlsb; extra == 'full'
Requires-Dist: streamlit; extra == 'full'
Requires-Dist: tespy>=0.10.1.post2; extra == 'full'
Requires-Dist: wakepy>=1.0.0; extra == 'full'
Provides-Extra: notebook
Requires-Dist: ipykernel>=7.2.0; extra == 'notebook'
Requires-Dist: nbformat>=5.10.4; extra == 'notebook'
Requires-Dist: openpyxl; extra == 'notebook'
Requires-Dist: plotly; extra == 'notebook'
Requires-Dist: pyxlsb; extra == 'notebook'
Provides-Extra: synthesis
Requires-Dist: gekko>=1.3.2; extra == 'synthesis'
Requires-Dist: idaes-pse>=2.11.0; extra == 'synthesis'
Requires-Dist: kaleido>=1.3.0; extra == 'synthesis'
Requires-Dist: openpyxl>=3.1.5; extra == 'synthesis'
Requires-Dist: plotly>=6.8.0; extra == 'synthesis'
Requires-Dist: pyomo>=6.10.0; extra == 'synthesis'
Requires-Dist: wakepy>=1.0.0; extra == 'synthesis'
Provides-Extra: tespy
Requires-Dist: tespy>=0.10.1.post2; extra == 'tespy'
Description-Content-Type: text/markdown

# OpenPinch

[![CI Develop](https://github.com/waikato-ahuora-smart-energy-systems/OpenPinch/actions/workflows/ci-develop.yml/badge.svg?branch=develop)](https://github.com/waikato-ahuora-smart-energy-systems/OpenPinch/actions/workflows/ci-develop.yml)
[![Documentation Status](https://readthedocs.org/projects/openpinch/badge/?version=latest)](https://openpinch.readthedocs.io/en/latest/)
[![PyPI version](https://img.shields.io/pypi/v/openpinch.svg)](https://pypi.org/project/OpenPinch/)
[![Python versions](https://img.shields.io/pypi/pyversions/openpinch.svg)](https://pypi.org/project/OpenPinch/)
[![License: MIT](https://img.shields.io/github/license/waikato-ahuora-smart-energy-systems/OpenPinch.svg)](LICENSE)

OpenPinch is an open-source Python toolkit for advanced Pinch Analysis and
Total Site Integration. It supports direct and indirect heat integration
targeting, graph interpretation, Heat Pump and refrigeration screening, exergy
and cogeneration post-processing, heat exchanger network synthesis,
multi-period analysis, stream piece-wise linearisation (for variable heat capacity
and phase change streams), and file-backed or schema-first workflows.

Full documentation is available at
https://openpinch.readthedocs.io/en/latest/.

## Install

Install the base package for validation, targeting, summaries, and schema-first
Python workflows:

```bash
python -m pip install openpinch
```

Install optional extras only for the workflows that need them:

```bash
python -m pip install "openpinch[notebook]"      # Jupyter, Plotly graphs, Excel I/O
python -m pip install "openpinch[dashboard]"     # Streamlit dashboard
python -m pip install "openpinch[synthesis]"     # HEN synthesis, then run: idaes get-extensions
python -m pip install "openpinch[brayton_cycle]" # TESPy-backed Brayton-cycle tooling
python -m pip install "openpinch[tespy]"          # TESPy HPR targeting and performance maps
python -m pip install "openpinch[full]"          # all optional surfaces, including synthesis
```

OpenPinch currently requires Python `>=3.14.2`.

Both `synthesis` and `full` install the IDAES/Pyomo synthesis stack. Complete
the IDAES installation before running solver-backed workflows:

```bash
idaes get-extensions
```

## First Solve

OpenPinch exposes two package-root workflow classes. Use `PinchProblem` for one
case and `PinchWorkspace` for named cases and scenarios.

```python
from OpenPinch import PinchProblem

problem = PinchProblem(
    {
        "streams": [
            {
                "name": "Hot feed",
                "zone": "Process",
                "t_supply": 180.0,
                "t_target": 80.0,
                "heat_flow": 1000.0,
            },
            {
                "name": "Cold feed",
                "zone": "Process",
                "t_supply": 20.0,
                "t_target": 120.0,
                "heat_flow": 800.0,
            },
        ],
        "utilities": [],
    },
    project_name="First solve",
)
problem.validate()
problem.target.all_heat_integration()

print(problem.summary_frame())
```

Analysis is explicit: named methods execute work, while summaries, reports,
plots, and exports consume prepared or cached state.

## Packaged Resources

OpenPinch ships maintained sample cases and notebook workflows. The resource
helpers below are useful repository tooling, but are not compatibility
protected:

```python
from OpenPinch.resources import (
    list_notebooks,
    list_sample_cases,
    notebook_metadata,
    sample_case_metadata,
)

print(list_sample_cases())
print(sample_case_metadata("basic_pinch.json").description)
print(list_notebooks())
print(notebook_metadata("01_first_solve_and_core_curves.ipynb").title)
```

Copy the notebook series from the CLI:

```bash
openpinch notebook -o notebooks
```

The nineteen-notebook series progresses from first solve through multiperiod
HPR, cogeneration, HEN synthesis, and publication workflows.

The CLI intentionally copies notebooks only. Solves, validation, graph export,
Excel export, dashboards, and advanced targeting happen through Python.

## Documentation Map

- Getting started: https://openpinch.readthedocs.io/en/latest/getting-started.html
- Workflow choice: https://openpinch.readthedocs.io/en/latest/overview/workflow-map.html
- Guides: https://openpinch.readthedocs.io/en/latest/guides/index.html
- API reference: https://openpinch.readthedocs.io/en/latest/api/index.html

## Testing

Run the test suite locally:

```bash
uv sync --frozen --group dev
uv run --no-sync ruff check .
uv run --no-sync coverage run --branch --source=OpenPinch -m pytest --hypothesis-seed=20260715 -m "not solver"
uv run --no-sync coverage report --fail-under=95
uv run --no-sync python scripts/build_docs.py
uv run --no-sync python scripts/build_dist.py
```

Ubuntu runs the complete CI suite. Windows and macOS install the generated
wheel and verify the core import, CLI, and packaged resources. Tests marked
`solver` require external solver binaries; the release workflow installs the
IDAES extensions and runs this gate automatically. Run it locally with
`uv run pytest -m solver` when the required binaries are available.

## Release Process

1. For a same-repository pull request targeting `main`, the PR workflow
   automatically advances an unchanged release version before validating it.
   A `major`, `minor`, or `patch` label takes precedence, followed by a matching
   title marker such as `[minor]`; the default is `patch`. The bump updates
   `pyproject.toml`, `uv.lock`, and `.bumpversion.toml` together without creating
   a tag. Fork pull requests remain read-only and must provide those synchronized
   forward-version changes in the contributor branch.
2. The ordered release-version job checks out and validates the updated PR head
   after the bump. Any later `synchronize` run or manual rerun recognizes the
   already-forward version without another commit. Merge only after the
   validation jobs, external-solver suite, and aggregate `pr-gate` result pass.
3. The main-branch workflow repeats the test, documentation, solver, build, and
   cross-platform artifact gates.
4. After those gates pass, it creates the annotated version tag and a draft
   GitHub release with checksummed release artifacts, then publishes the same
   distributions to TestPyPI. Preflight and postflight checks require the exact
   expected filenames and SHA-256 hashes, including safe recovery from a
   partial upload.
5. After TestPyPI succeeds:
   - it publishes the GitHub release before production PyPI
   - it dispatches the same workflow at the version tag
6. The tag-ref run verifies the source push, workflow, prerequisite jobs, and
   immutable build artifact ID, digest, and build attempt. It then requires the
   public release files to match that artifact byte-for-byte without rebuilding
   and waits at the protected `pypi` environment.
7. Approve that deployment to use PyPI Trusted Publishing; the workflow uploads
   the verified distributions and confirms the version through the PyPI API.

The automatic pull-request bump is idempotent: a candidate already greater than
the base is validated without another commit, while a candidate behind the base
fails for manual reconciliation. Version bumping does not create a tag. The
release workflow owns tags and rejects malformed versions, mismatched lock
metadata, or an existing tag that points anywhere other than the main-branch
release commit. If production
publication or its availability check fails after the GitHub Release becomes
public, open the original tag run and select **Re-run failed jobs**. Exact index
preflight, `skip-existing`, and a separately retryable availability check make
an absent, partial, or already-complete release recoverable without accepting
mismatched files. Do not start a fresh tag dispatch when the upload may already
have succeeded.

Build the documentation locally:

```bash
uv run scripts/build_docs.py
```

## History and Citation

OpenPinch started in 2011 as an Excel workbook with macros. The Python
implementation began in 2021 to make the workflows scriptable and testable.

In publications and forks, please cite and link the foundational article and
this repository:

Timothy Gordon Walmsley, 2026. OpenPinch: An Open-Source Python Library for
Advanced Pinch Analysis and Total Site Integration. Process Integration and
Optimization for Sustainability. https://doi.org/10.1007/s41660-026-00729-6

## Contributors

Founder: Tim Walmsley, University of Waikato

Stephen Burroughs, Benjamin Lincoln, Alex Geary, Harrison Whiting, Khang Tran,
Roger Padulles, Jasper Walden, Caleb Archer

## License

OpenPinch is released under the MIT License. See `LICENSE` for details.
