We envision GDPlib as an open library of GDP models to provide examples for prospective modelers, and to provide a benchmarking set for algorithm developers. We invite contributions to this library from the community, provided under the same BSD-3-clause or compatible license.
The following table shows the size metrics for GDPlib models:
| Component | batch_processing | biofuel | cstr | disease_model | ex1_linan_2023 | gdp_col | grid | hda | jobshop | kaibel | med_term_purchasing | methanol | mod_hens: conventional | mod_hens: mixed_discrete | mod_hens: mixed_integer | mod_hens: multiple_module_discrete | mod_hens: multiple_module_integer | mod_hens: single_module_discrete | mod_hens: single_module_integer | modprodnet: Decay | modprodnet: Dip | modprodnet: Distributed | modprodnet: Growth | modprodnet: QuarterDistributed | multiperiod_blending: mpbp_6 | pandemic | positioning | reverse_electrodialysis | small_batch | spectralog | stranded_gas: Gas_100 | stranded_gas: Gas_250 | stranded_gas: Gas_500 | stranded_gas: Gas_large | stranded_gas: Gas_small | syngas | water_network: none | water_network: piecewise | water_network: quadratic_nonzero_origin | water_network: quadratic_zero_origin |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Variables | 288 | 36840 | 76 | 1250 | 12 | 442 | 47525 | 1158 | 10 | 4033 | 1165 | 287 | 338 | 3802 | 498 | 3802 | 498 | 4761 | 501 | 488 | 488 | 3720 | 488 | 1320 | 726 | 1221 | 56 | 776 | 37 | 128 | 8799 | 8799 | 8799 | 11682 | 11682 | 367 | 395 | 1405 | 395 | 420 |
| Binary variables | 138 | 516 | 20 | 52 | 10 | 30 | 35000 | 12 | 6 | 200 | 216 | 8 | 64 | 1728 | 128 | 1728 | 128 | 2147 | 131 | 2 | 2 | 42 | 2 | 42 | 252 | 222 | 50 | 8 | 18 | 60 | 158 | 158 | 158 | 160 | 160 | 46 | 10 | 510 | 10 | 10 |
| Integer variables | 0 | 4356 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 96 | 0 | 96 | 0 | 96 | 363 | 363 | 1452 | 363 | 492 | 0 | 0 | 0 | 0 | 0 | 0 | 2520 | 2520 | 2520 | 5040 | 5040 | 0 | 0 | 0 | 0 | 0 |
| Continuous variables | 150 | 31968 | 56 | 1198 | 2 | 412 | 12525 | 1146 | 4 | 3833 | 949 | 279 | 274 | 2074 | 274 | 2074 | 274 | 2614 | 274 | 123 | 123 | 2226 | 123 | 786 | 474 | 999 | 6 | 768 | 19 | 68 | 6121 | 6121 | 6121 | 6482 | 6482 | 321 | 385 | 895 | 385 | 410 |
| Disjunctions | 9 | 252 | 10 | 26 | 2 | 15 | 12500 | 6 | 3 | 100 | 72 | 4 | 32 | 64 | 64 | 64 | 64 | 33 | 65 | 1 | 1 | 21 | 1 | 21 | 126 | 111 | 25 | 4 | 9 | 30 | 79 | 79 | 79 | 80 | 80 | 23 | 5 | 5 | 5 | 5 |
| Disjuncts | 18 | 516 | 20 | 52 | 10 | 30 | 35000 | 12 | 6 | 200 | 216 | 8 | 64 | 128 | 128 | 128 | 128 | 67 | 131 | 2 | 2 | 42 | 2 | 42 | 252 | 222 | 50 | 8 | 18 | 60 | 158 | 158 | 158 | 160 | 160 | 46 | 10 | 10 | 10 | 10 |
| Constraints | 601 | 12884 | 112 | 831 | 10 | 610 | 52000 | 728 | 9 | 5790 | 762 | 429 | 370 | 5362 | 562 | 5362 | 562 | 8786 | 565 | 486 | 486 | 1792 | 486 | 672 | 1020 | 1107 | 30 | 794 | 34 | 158 | 2668 | 2668 | 2668 | 3391 | 3391 | 543 | 329 | 1339 | 329 | 334 |
| Nonlinear constraints | 1 | 12 | 17 | 0 | 0 | 262 | 0 | 151 | 0 | 2128 | 0 | 55 | 96 | 96 | 96 | 96 | 96 | 32 | 96 | 1 | 1 | 36 | 1 | 36 | 60 | 220 | 25 | 162 | 1 | 8 | 1 | 1 | 1 | 2 | 2 | 48 | 33 | 28 | 33 | 33 |
This table was automatically generated using the generate_model_size_report.py script.
GDPlib is an installable model library in Python. To install GDPlib, you can use:
pip install gdplib
To update GDPlib:
pip install --upgrade gdplib
For a developer install, please clone this repository, activate the correct python environment, and run:
pip install -r requirements.txt
pip install -e .For development work on Linux, use the Pixi environment when available. The
committed Pixi lock currently targets linux-64; on other platforms, use the
pip workflow below or add the appropriate Pixi platform and regenerate the lock
file.
pixi install
pixi run test
pixi run lintThe committed Pixi support surface is linux-64 only because that is the
platform the maintainers can verify with pixi install, pixi run test, and
pixi run lint. The pixi.lock file should cover exactly the platforms listed
in pixi.toml; do not commit lock-file changes for osx-64, osx-arm64,
win-64, or another platform unless that platform has been added deliberately
and verified with the same commands. macOS and Windows users should use the pip
workflow unless a PR explicitly adds and verifies Pixi support for those
platforms.
The default Pixi environment intentionally excludes optional external optimization solver stacks and licensed solver bindings. Keep GAMS, BARON, IPOPT, Gurobi, HiGHS, and similar tools in optional local environments, benchmark profiles, or documentation unless they become required for default imports and tests.
For direct Gurobi access through Pyomo's Python interfaces, use the optional
Pixi environment with gurobipy and point Gurobi at a valid license:
export GRB_LICENSE_FILE=/path/to/gurobi.lic
pixi install -e gurobi
pixi run -e gurobi python -c "import gurobipy as gp; from pyomo.environ import SolverFactory; print(gp.gurobi.version()); print(SolverFactory('gurobi_direct').available(False))"Pyomo's direct Gurobi interfaces support many LP, MIP, and quadratic workflows. For nonlinear transformed GDP models that Pyomo cannot write directly to Gurobi, use the documented GAMS/Gurobi benchmark profile.
PyPI releases are published by
.github/workflows/publish.yml when a
GitHub Release is published. Package versions come from git tags through
setuptools_scm, so create the release from the version tag intended for PyPI.
The build backend remains setuptools.build_meta as configured in
pyproject.toml, and package maintainer metadata remains defined there.
The publish workflow checks out full git history, builds both the sdist and
wheel with python -m build, validates them with
python -m twine check dist/*, installs the wheel on Python 3.10, 3.11, and
3.12, and then publishes with PyPI Trusted Publishing through the protected
pypi GitHub environment. The PyPI project must have a trusted publisher entry
for this repository, the publish.yml workflow, and the pypi environment
before publishing the first release.
Before publishing a GitHub Release, run the normal local checks:
pixi run test
pixi run lintIf local artifact validation is needed, install the PyPA build tools in the active environment and run:
python -m build
python -m twine check dist/*The committed Pixi environment remains linux-64 only. Do not add Pixi
platforms for release work unless the lock file is regenerated and the selected
platforms are verified according to the development policy above.
The benchmark runner can preflight the PR #58 benchmark campaign before starting long solver-backed runs. Preflight checks the selected strategy plugins, solver interface, GAMS executable when applicable, and model construction.
The default profile is a local nonlinear GAMS profile that uses DICOPT for
transformed and local MINLP roles, IPOPTH for NLP roles, and Gurobi for MIP
roles. This is the recommended first pass before launching a global GAMS/BARON
run. Use --solver-profile gams-gurobi for a GAMS/Gurobi pass, or
--solver-profile gams-baron for a global BARON pass.
GAMS-backed benchmark solves use option optcr=1e-6 by default so incumbent
solutions and solver bounds are compared at a consistent relative gap.
pixi run gdplib-benchmark preflightTo run the PR #58 campaign with the local nonlinear GAMS profile and 1-hour per-case time limits:
pixi run gdplib-benchmark run --cases-file benchmark_cases/pr58_local.csv --run-id pr58_localFor row-by-row control over instances, methods, and subsolvers, pass a case file:
pixi run gdplib-benchmark run --cases-file benchmark_cases.csv --run-id pr58_casesCSV columns may include instance, strategy, timelimit, solver_profile,
subsolver, gams_solver, gams_nlp_solver, gams_mip_solver,
gams_minlp_solver, gams_local_minlp_solver, and label.
After the local nonlinear run has identified construction, transformation, and local solver issues, run the global GAMS/BARON profile explicitly:
pixi run gdplib-benchmark run --solver-profile gams-baron --run-id pr58_globalTo capture Pyomo/Python warnings from the same model set without starting solver-backed benchmark jobs:
pixi run gdplib-benchmark warnings --run-id pr58_warningsBenchmark outputs are generated under gdplib/<model>/benchmark_result/<run-id>/.
Aggregate run metadata, strict JSON summaries, and failure manifests are written
under benchmark_runs/<run-id>/. These generated outputs are ignored by git.
For a pip-based setup:
-
Install development dependencies:
pip install -r requirements.txt pip install -r requirements-dev.txt pip install -e . -
Set up GitHub Copilot with custom instructions:
- The repository includes custom Copilot instructions in
.github/copilot-instructions.md - Project-specific configurations are available in
.copilot/
- The repository includes custom Copilot instructions in
-
Run tests:
pytest tests/ -v --tb=short
-
Code formatting and linting:
black -S -C --target-version py310 --check --diff . flake8 gdplib/ --count --select=E9,F63,F7,F82 --show-source --statistics flake8 gdplib/ --count --exit-zero --max-complexity=10 --max-line-length=88 --statisticsThe
typosCLI used by CI is included in the Pixi environment. Install it separately before running the spell check from a pip-only environment:typos --config ./.github/workflows/typos.toml
Details for each model are given in a separate README.md file in each directory. Navigate to these directories to read the files.
Once GDPlib is installed, functions for constructing the desired models can be imported from each of the main subpackages.
For example, biofuel/__init__.py exposes a build_model function, allowing the user to write the following:
from gdplib.biofuel import build_model as build_biofuel_model
pyomo_model = build_biofuel_model()To add new models to the library, the following steps should be taken:
- Ensure that you have the requisite permissions to contribute the model to an open source library.
- Add your files into one of the existing directories or a new project directory:
gdplib/mynewmodel. - If a new directory is created, add the corresponding import to
gdplib/__init__.py. - Within your project directory, add the requisite imports and edits to the
__all__statement ingdplib/mynewmodel/__init__.pyto expose the appropriate build functions. See the other project directories for examples. - Within your project directory, create a
README.mdfile describing the new model.
Directories are free to implement their own subpackages.
Note that __main__ scripts within projects (i.e. those that you plan to execute directly) will need to use absolute imports rather than relative imports.
For example, in gdplib/gdp_col/main.py, we need to write from gdplib.gdp_col.fenske import calculate_Fenske rather than from .fenske import calculate_Fenske.