Skip to content
process-intensification-labPublic

About

Python simulator of adsorption cycles for CO2 direct air capture in 1D and 2D packed beds: steam-assisted TVSA by default, cyclic steady state with KPIs, NSGA-II optimization.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

pyDAC

PyPI Python versions CI Downloads DOI

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.1.0, development status Beta. MIT license.

Using pyDAC? Make sure you always run the latest version. pyDAC is under active development and new releases come out often. To be notified when a new version is available, please click Watch → Custom → Releases on the GitHub page. To update, run python -m pip install --upgrade pydac3 in the pyDAC environment (see Update or remove).

README.mp4

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 .

This takes the newest dependency versions that pyDAC allows, as pip install pydac3 does. For the pinned versions of the release, see Exact reproduction. 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. One lock file serves Linux and Windows. Linux, with venv:

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 .

The last line installs a fixed copy of the clone, as pip install pydac3 does: later edits in src/pydac/ are not used. To change pyDAC on the exact environment, install it in editable mode instead, with python -m pip install --no-deps -e ..

Windows, in PowerShell, with the py launcher (the same lock file):

py -3.12 -m venv pydac-exact
pydac-exact\Scripts\Activate.ps1
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, register_bed_architecture, BedArchitectureEntry, ClosureInputs, ResolvedStructure, ResolvedTransport, ContextParameter, solve_quadratic_drag_velocity 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 the pyDAC paper, available as a preprint on ChemRxiv:

M. Galanti, I. Roghair, M. van Sint Annaland. pyDAC: Open-Source two-dimensional modeling of s-TVSA for direct air capture: experimental assessment and validity of one-dimensional approximations. ChemRxiv (2026). doi:10.26434/chemrxiv.15010382/v1

and the software itself with the metadata in CITATION.cff. Each GitHub release has its own DOI on Zenodo; 10.5281/zenodo.23319859 always resolves to the latest version.

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.

About

Python simulator of adsorption cycles for CO2 direct air capture in 1D and 2D packed beds: steam-assisted TVSA by default, cyclic steady state with KPIs, NSGA-II optimization.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages