Skip to main content

Python-based User-defined Lifecycle Production Optimization

Jupyter Python Markdown

License Last Commit Commit Activity

PyPI - Version GitHub Stars


📍 Overview

PULPO is a Python package for Life Cycle Optimization (LCO) based on life cycle inventories. It is designed to serve as a platform for optimization tasks of varying complexity.

The package builds on top of the Brightway LCA framework and the Pyomo optimization modeling framework.


✨ Capabilities

Applying optimization is recommended when the system of study has (1) many degrees of freedom that would otherwise prompt the manual assessment of a large number of scenarios, or (2) any of the following capabilities is relevant to the goal and scope of the study:

  • Specify technology and regional choices throughout the entire supply chain (fore- and background), such as the production technology of electricity or the origin of metal resources. Consistently accounting for background changes in large-scale decisions can be significant.
  • Specify constraints on any activity in the life cycle inventories, interpreted as tangible limitations such as raw material availability, production capacity, or environmental regulations.
  • Optimize for or constrain any impact category for which characterization factors are available.
  • Specify supply values instead of final demands, which is relevant when only production volumes are known (e.g. here).
  • Optimize under uncertainty via a dedicated pipeline: import and filter uncertain LCI parameters, apply uncertainty strategies, run Global Sensitivity Analysis (Sobol), perform Monte Carlo sampling, or solve Chance-Constrained programs to obtain Pareto-optimal solutions at user-defined probability levels.

Features recently completed:

  • ℹ️ Optimization under uncertainty [chance-constraints, Monte Carlo, global sensitivity analysis]
  • ℹ️ Time-dependent optimization [time-indexed formulation with inter-timestep storage/carry-over]
  • ℹ️ Development of a GUI for simple optimization tasks Link
  • ℹ️ Enable PULPO to work on both bw2 and bw25 projects
  • ℹ️ Thorough documentation hosted on flechtenberg.github.io/pulpo/
  • ℹ️ Goal-programming objective (average transgression of soft impact limits)
  • ℹ️ Exact chance-constrained optimization (second-order cone, joint risk budgets, exact bound quantiles)
  • ℹ️ Numerical scaling of the LP for unaggregated ecoinvent backgrounds

Features currently under development:

  • ℹ️ Integration of economic and social indicators in the optimization problem formulation

Feature requests are more than welcome!


🔧 Installation

PULPO is available on PyPI. Depending on the version of Brightway you want to work with, install either the bw2 or bw25 variant:

pip install "pulpo-dev[bw2]"

or

pip install "pulpo-dev[bw25]"

Add the uncertainty extra (SALib, stats_arrays, seaborn) if you plan to use the pulpo_unc module for Monte Carlo, Chance-Constrained optimization, or Global Sensitivity Analysis:

pip install "pulpo-dev[bw25,uncertainty]"

🤖 Running PULPO

PULPO is organized into three optimizer classes, one per module, each covering a different use case with its own reference notebook:

  • pulpo.pulpo.PulpoOptimizer — the core LCO framework: technology/region choices, constraints, single- and multi-objective optimization (including goal programming), and supply-driven optimization. Start with the PULPO showcase notebook, a complete walkthrough built around a methanol production case.
  • pulpo.pulpo_time.PulpoOptimizerTime — the time-indexed extension: per-timestep demands and limits, impact budgets aggregated across the horizon, and inter-timestep storage/carry-over. See the time-dependent toy notebook for hourly and daily battery-dispatch examples.
  • pulpo.pulpo_unc.PulpoOptimizerUnc — the uncertainty extension: import and filter uncertain LCI parameters, apply gap-filling strategies, run Monte Carlo sampling, Chance-Constrained optimization, and Global Sensitivity Analysis. See the uncertainty toy notebook.

Additional example notebooks are available for a hydrogen case, an electricity case, and a plastic case.

There is also a workshop repository (here) created for the Brightcon 2024 conference, with guided notebooks and exercises.

🧪 Tests

The test suite runs with pytest against dedicated virtual environments for the modern (bw25) and legacy (bw2) Brightway stacks. See the testing README for setup instructions and the exact commands.


What's new in 1.8.0?

  • Exact chance-constrained optimizationcreate_SOC_formulation() / solve_SOC_problem() represent the impact's standard deviation exactly as a second-order cone, including the covariance that processes share through a common characterization factor, rather than by the conservative L1 bound that solve_CC_problem uses. The default cutting-plane strategy solves a sequence of the ordinary LPs PULPO already builds, which is what makes it tractable at ecoinvent scale. Joint chance constraints across several rows (risk_budget=) and exact quantiles for uncertain bounds (bound_quantile='exact') are available alongside it.
  • Optional LP equilibrationinstantiate(scale=True) rescales the LP by powers of two so a facility-scale row cannot be under-supplied within the solver's feasibility tolerance. On an unaggregated ecoinvent background that leak was worth roughly 1 % of the optimum and made different solvers disagree. The solution is unscaled after the solve, so every result still reads in original units.
  • From 1.7.0: goal-programming objectiveobjective='goal' minimizes the average transgression of user-defined soft impact limits (imp_goals), reported per category via extract_results()["Transgressions"].

See the changelog for the full details and earlier releases.


🤝 Contributing

Contributions are very welcome. To request a feature or report a bug, please open an Issue. If you are confident in your coding skills, feel free to implement your suggestions and send a Pull Request.


📄 License

This project is licensed under the ℹ️ BSD 3-Clause License. See the LICENSE file for additional info.
Copyright (c) 2026, Fabian Lechtenberg. All rights reserved.


👏 Acknowledgments

We would like to express our gratitude to the authors and contributors of the following packages that PULPO builds upon:

We also acknowledge the pioneering ideas and contributions from the following works:

The development of PULPO culminated in the following publication, which details the approach and outlines its implementation:

Fabian Lechtenberg, Robert Istrate, Victor Tulus, Antonio Espuña, Moisès Graells, and Gonzalo Guillén‐Gosálbez.
“PULPO: A Framework for Efficient Integration of Life Cycle Inventory Models into Life Cycle Product Optimization.”
Journal of Industrial Ecology, October 10, 2024.
https://doi.org/10.1111/jiec.13561

Please cite this article if PULPO is used to produce results for a publication or project.


Authors


↑ Return

Release files for pulpo-dev 1.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pulpo-dev 1.8.0
File Size Uploaded
pulpo_dev-1.8.0.tar.gz 155.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pulpo-dev 1.8.0
File Interpreter ABI Platform
pulpo_dev-1.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 286.9 kB

Release files / pulpo_dev-1.8.0.tar.gz

Download URL pulpo_dev-1.8.0.tar.gz
Size 155.7 kB
Tags Source
SHA-256 checksum
How to use checksums
729e28e88de47abe3bd90b4f8e104f74c04bdd60546198e21564eec0e4f5fcbb
BLAKE2b-256 checksum
How to use checksums
c0311e8934294a5006ddd3db7e0043245d52e00d9170310fc19f4ab85e0dcda7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pulpo_dev-1.8.0-py3-none-any.whl

Download URL pulpo_dev-1.8.0-py3-none-any.whl
Size 131.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6066eb4178bd26a74802675ce86f76f5f36c53684a0bdc7a5796334955db2dd0
BLAKE2b-256 checksum
How to use checksums
89c93022c0a2ef1585e617f27501be15dfb626f1ed98f0e523f76375528d9c8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.8.0 This release

2 release files

1.7.0

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page