pyDAC
pyDAC simulates adsorption-based direct air capture (DAC) processes. It solves the coupled mass, energy and momentum balances of a sorbent column in 1D or 2D (axisymmetric) and runs adsorption cycles step by step or to cyclic steady state (CSS). A cycle is composed from configurable steps (adsorption, blowdown, heating, purge, steam- or wall-heated desorption, cooling, pressurization); the default is a steam-assisted temperature-vacuum swing adsorption (TVSA) cycle. pyDAC reports process key performance indicators (KPIs) and optimizes operating conditions with the NSGA-II genetic algorithm (non-dominated sorting genetic algorithm II).
pyDAC 3.0.0, development status Beta. MIT license.
Installation
1. Create a dedicated environment
Install pyDAC in an environment of its own: never in the system Python, a conda base
environment, or an environment shared with other projects. pyDAC fixes the versions of
some dependencies (pymrm==2.1.10, pandas<3, scikit-sundae 1.1.x), and pip silently
replaces versions that are already installed, so a shared environment can break pyDAC
or the other project without any message.
Linux, with venv:
python3 -m venv pydac-env
source pydac-env/bin/activate
Windows (PowerShell), with venv:
py -m venv pydac-env
pydac-env\Scripts\Activate.ps1
With conda instead:
conda create -n pydac python=3.12
conda activate pydac
With uv instead (uv environments have no pip; write uv pip where this page writes
python -m pip):
uv venv pydac-env
source pydac-env/bin/activate
2. Install pyDAC
python -m pip install pydac3
The distribution is called pydac3; the package you import and the command you run are
both pydac. pip install pydac installs an unrelated project.
One install contains everything: step runs, CSS runs, case validation and NSGA-II
optimization (pymoo is a regular dependency). pydac get-started my_pydac copies the tutorials
and the user guide into a new folder
(Get the tutorials). The optional extra completion adds shell
completion for the pydac command (python -m pip install "pydac3[completion]").
Python 3.11 to 3.14 on Linux (x86_64) is supported. Windows is being tested; macOS is neither tested nor supported.
Want to adapt pyDAC to your own needs, or help improve it? Install it from a clone in
editable mode instead; then an edit in src/pydac/ is used at the next import:
git clone https://github.com/process-intensification-lab/pyDAC.git
cd pyDAC
python -m pip install -e .
CONTRIBUTING.md gives the full procedure (dedicated environment, light or
exact dependencies, tests) and how to propose a change.
3. Check the environment
python -m pip check
pydac --version
python -c "import pydac; print(pydac.__file__)"
pip check must report no broken requirements, and the printed path must lie inside
the environment you created. A path in the user site instead (for example under
~/.local/lib/) means a user-site installation shadows the environment; set
PYTHONNOUSERSITE=1 or remove that installation.
When the pydac command runs outside a virtual environment or a conda environment
other than base, it prints a one-line warning on stderr and continues. Set
PYDAC_NO_ENV_WARNING=1 to silence it, for example in a container that uses the system
Python on purpose. import pydac never prints it.
Exact reproduction
To reproduce the qualified environment exactly (every package pinned, with hashes; Python 3.12), install from the lock file into a second fresh environment, from the root of a clone:
python3.12 -m venv pydac-exact
source pydac-exact/bin/activate
python -m pip install --require-hashes -r ci/qualification-lock-py3.12.txt
python -m pip install --no-deps .
Tutorials
The best way to learn pyDAC is the seven tutorials. Start with
01 First steps, then follow them in order.
pydac get-started my_pydac copies them, with the user guide, into a new folder. Each
tutorial is a notebook and states its runtime (from a few minutes to about 40). Tutorials
01-06 also run from the terminal, with the commands in examples/README.md;
tutorial 07 needs Python, because it registers its own isotherm.
| Tutorial | What it shows |
|---|---|
| 01 First steps | a step run, the KPI table of each step, step profile plots, time- or event-based stop |
| 02 Build your own case | replace the defaults block by block (column, gas, sorbent, isotherm, kinetics, steps); a 2D TSA step run |
| 03 A cycle at its periodic state | a CSS run of the built-in TVSA cycle in 2D, the cycle KPIs, where the CO2 and the energy go |
| 04 1D or 2D | the same cycle in 1D, in 2D and in 2D with wall channeling |
| 05 An optimization campaign | a trial NSGA-II campaign: variables, bounds, constraints, the Pareto front |
| 06 Reproduce the breakthrough validation | the 2D model of the pyDAC paper against the measurements of Zanco et al. |
| 07 Your own isotherm | a new sorbent from the literature, its isotherm registered from Python and run |
Quick start from the terminal
A case is the complete set of inputs of one simulation. Write the built-in case to a file, here with a coarse 1D grid and at most three cycles:
pydac validate --set grid.nz=25 --set grid.nr=1 --set execution.max_cycles=3 --set execution.require_css=false --export-case my_case.json
my_case.json holds every input of the simulation. To change it, prefer settings over
editing the file: they recompute the fields that depend on others, such as the bed length
from its volume (Cases and settings). Then run it exactly as
saved; it repeats the cycle until cyclic steady state, here for at most three cycles;
this coarse case reaches CSS at cycle 3:
pydac css --case my_case.json
The run takes one to two minutes. It writes everything under
simulation_results/cyclic_mode/packed_bed_XXXXXXXX/, where XXXXXXXX is the start of
the case fingerprint, and prints that run folder as its last line. Inside,
1D_mode/cycle_N/ holds each cycle and 1D_mode/kpis/ the KPI tables of the final
cycle. Running the same case again is refused while that folder exists: continue it with
--resume, replace it with --overwrite, or set another execution.extra_tag.
The other commands are pydac steps (startup, then each listed step once),
pydac nsga2 (an optimization campaign) and pydac validate. Each lists its options
with --help; pydac validate --show-settings lists the settings with their built-in
defaults. Instead of a complete case, --config takes a partial preset whose omitted
fields take the built-in defaults, for example
examples/cases/quick_1D.json from the repository:
pydac css --config examples/cases/quick_1D.json --dry-run
Exit codes: 0 success, 1 failure after the run started, 2 invalid command-line
arguments, configuration error or refused request, 3 CSS not reached while
execution.require_css is true.
Quick start from Python
The same steps through the Python API, in a script or a notebook. This loads the saved case, changes one setting, runs it and reads two KPIs:
import pydac
case = pydac.load_case("my_case.json", settings={"execution.max_cycles": 4})
result = pydac.run_css(case)
print(result.folder, result.css_reached, result.cycle)
kpis = pydac.CycleKPIs(pydac.CycleDataLoader(result.folder).load())
print(f"CO2 recovery: {100 * kpis.recovery('CO2'):.1f} %")
print(f"Productivity: {kpis.productivity():.2f} kg CO2 per m3 bed per day")
pydac.load_case(path, exact=True) runs a complete case exactly, as --case does. The
supported API is the set of names in pydac.__all__: load_case, export_case,
export_settings, run_steps, run_css, run_nsga2, resume, report, get_started,
RunResult, ConfigurationError, RunRefused, ExperimentConfig, CycleDataLoader,
CycleKPIs, register_equilibrium, register_kinetics, EquilibriumSystem, KineticLaw,
EquilibriumRegistryEntry, KineticRegistryEntry and the version string __version__.
Reproducibility
Every run folder contains the resolved case (resolved_config.json), its fingerprint
(case_metadata.json) and a provenance record: the pyDAC version, the Python version,
the platform and the versions of the numerical dependencies. Run from a clone, the
record also says whether the checkout had uncommitted changes; it does not record the Git
revision, so keep the commit of an unreleased checkout yourself. To
rerun a result, run its resolved_config.json with --case (in another output root, or
with --overwrite); to rebuild the environment, use the lock file above.
Documentation
Read in this order: the tutorials (above) teach pyDAC on real runs; the user guide is
the reference for using it, in more technical detail; the reference manual describes how pyDAC
works inside, in full technical detail, for contributors and for checking the model. The
documentation index is docs/README.md. The user guide explains how to use
pyDAC:
- Installation: environments, Jupyter, shell completion, exact reproduction, troubleshooting.
- Quick start: one case from the terminal, a script and a notebook; the Python API and its errors.
- Cases and settings: presets, settings, frozen cases,
model choices,
null, fingerprints. - Running steps and cycles: step sequence, stop rules, resume, replay, report, run folders, exit codes.
- Optimization campaigns: NSGA-II campaigns, bounds, constraints, stop rules, continuing and reporting a campaign.
- Results: run folders, KPI files, reading results from Python, which folders to trust.
- Reproducibility: sharing a case, provenance, the exact environment, compatibility across versions.
- Extending pyDAC: your own isotherms and kinetic laws, registered from Python; what needs a change to the package.
The reference chapters describe the model and the code:
| Chapter | Contents |
|---|---|
00_framework_map.md |
Layers, entry points and what a run does end to end |
01_inputs.md |
Cases, presets, settings and the case document |
02_pydac_core.md |
Model construction, state vector, solver and cycle orchestration |
03_pymrm_discretization.md |
Finite-volume operators and boundary conditions |
04_governing_equations.md |
Balances and closures, and where the code assembles them |
05_cycle_steps.md |
Each cycle step: physics, boundary conditions, stop rules |
06_post_processing.md |
KPIs, separators, plots and result files |
07_nsga2_optimization.md |
NSGA-II campaigns |
To work on pyDAC itself, read CONTRIBUTING.md.
How to cite
If you use pyDAC in your research, please cite it with the metadata in
CITATION.cff. Each GitHub release has its own DOI on Zenodo; once the
pyDAC paper is published, it becomes the preferred citation.
License and authors
pyDAC is released under the MIT license (LICENSE). Authors: Mattia
Galanti, Ivo Roghair and Martin van Sint Annaland (Eindhoven University of Technology).
Maintainer: Mattia Galanti.
Acknowledgements
We thank Shell Global Solutions International BV for financial support.
Metadata
Release files for pydac3 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydac3-3.0.0.tar.gz | 4.3 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydac3-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 8.3 MB
Release files / pydac3-3.0.0.tar.gz
| Download URL | pydac3-3.0.0.tar.gz |
|---|---|
| Size | 4.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c3694835b9acddbd62d906b2320f21e2d3d178c991f7c6af79ba52416ac362e7
|
|
BLAKE2b-256 checksum How to use checksums |
c186efd3d3c08a797b34dcc2654530fb4012c6fc282de960d5e67bc76f82cce3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / pydac3-3.0.0-py3-none-any.whl
| Download URL | pydac3-3.0.0-py3-none-any.whl |
|---|---|
| Size | 4.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5bca3b32d3fe9a47453508f83b2ee02952e5cea329a08b4ed0b331aca1023911
|
|
BLAKE2b-256 checksum How to use checksums |
6240764cd1d4e58255856822be6f9bc01d7047db830bf0610e73d19464bb1818
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log