pydac3 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pydac3-3.0.0/.gitignore +44 -0
- pydac3-3.0.0/CITATION.cff +29 -0
- pydac3-3.0.0/CONTRIBUTING.md +240 -0
- pydac3-3.0.0/LICENSE +21 -0
- pydac3-3.0.0/PKG-INFO +298 -0
- pydac3-3.0.0/README.md +262 -0
- pydac3-3.0.0/ci/qualification-lock-py3.12.txt +2049 -0
- pydac3-3.0.0/docs/.gitignore +2 -0
- pydac3-3.0.0/docs/README.md +57 -0
- pydac3-3.0.0/docs/check_links.py +139 -0
- pydac3-3.0.0/docs/guide/01_installation.md +244 -0
- pydac3-3.0.0/docs/guide/02_quickstart.md +255 -0
- pydac3-3.0.0/docs/guide/03_cases.md +287 -0
- pydac3-3.0.0/docs/guide/04_running.md +311 -0
- pydac3-3.0.0/docs/guide/05_optimization.md +306 -0
- pydac3-3.0.0/docs/guide/06_results.md +287 -0
- pydac3-3.0.0/docs/guide/07_reproducibility.md +133 -0
- pydac3-3.0.0/docs/guide/08_extending.md +231 -0
- pydac3-3.0.0/docs/manual/00_framework_map.md +372 -0
- pydac3-3.0.0/docs/manual/01_inputs.md +943 -0
- pydac3-3.0.0/docs/manual/02_pydac_core.md +637 -0
- pydac3-3.0.0/docs/manual/03_pymrm_discretization.md +316 -0
- pydac3-3.0.0/docs/manual/04_governing_equations.md +387 -0
- pydac3-3.0.0/docs/manual/05_cycle_steps.md +558 -0
- pydac3-3.0.0/docs/manual/06_post_processing.md +2100 -0
- pydac3-3.0.0/docs/manual/07_nsga2_optimization.md +202 -0
- pydac3-3.0.0/examples/README.md +117 -0
- pydac3-3.0.0/examples/cases/01_first_steps.json +16 -0
- pydac3-3.0.0/examples/cases/02_custom_case.json +86 -0
- pydac3-3.0.0/examples/cases/03_css_tvsa.json +16 -0
- pydac3-3.0.0/examples/cases/04_1d_vs_2d.json +18 -0
- pydac3-3.0.0/examples/cases/05_nsga2_bounds.json +8 -0
- pydac3-3.0.0/examples/cases/05_nsga2_trial.json +15 -0
- pydac3-3.0.0/examples/cases/06_breakthrough_validation.json +120 -0
- pydac3-3.0.0/examples/cases/07_apdes_nfc_sorbent.json +34 -0
- pydac3-3.0.0/examples/cases/07_new_isotherm.json +18 -0
- pydac3-3.0.0/examples/cases/quick_1D.json +33 -0
- pydac3-3.0.0/examples/data/zanco2022_13x/README.md +51 -0
- pydac3-3.0.0/examples/data/zanco2022_13x/center.csv +902 -0
- pydac3-3.0.0/examples/data/zanco2022_13x/co2.csv +595 -0
- pydac3-3.0.0/examples/data/zanco2022_13x/half_radius.csv +902 -0
- pydac3-3.0.0/examples/data/zanco2022_13x/wall.csv +902 -0
- pydac3-3.0.0/examples/notebooks/01_first_steps.ipynb +895 -0
- pydac3-3.0.0/examples/notebooks/02_custom_case.ipynb +3347 -0
- pydac3-3.0.0/examples/notebooks/03_css_tvsa.ipynb +6480 -0
- pydac3-3.0.0/examples/notebooks/04_1d_vs_2d.ipynb +959 -0
- pydac3-3.0.0/examples/notebooks/05_nsga2_trial.ipynb +1890 -0
- pydac3-3.0.0/examples/notebooks/06_breakthrough_validation.ipynb +673 -0
- pydac3-3.0.0/examples/notebooks/07_new_isotherm.ipynb +860 -0
- pydac3-3.0.0/pyproject.toml +109 -0
- pydac3-3.0.0/runners/__init__.py +1 -0
- pydac3-3.0.0/runners/run_NSGA2.py +34 -0
- pydac3-3.0.0/runners/run_css_simulation.py +86 -0
- pydac3-3.0.0/runners/run_steps_simulation.py +85 -0
- pydac3-3.0.0/runners/validate_config.py +16 -0
- pydac3-3.0.0/src/pydac/__init__.py +59 -0
- pydac3-3.0.0/src/pydac/api.py +1022 -0
- pydac3-3.0.0/src/pydac/cli.py +596 -0
- pydac3-3.0.0/src/pydac/config/__init__.py +116 -0
- pydac3-3.0.0/src/pydac/config/bed_profiles.py +32 -0
- pydac3-3.0.0/src/pydac/config/cli.py +138 -0
- pydac3-3.0.0/src/pydac/config/contract.py +147 -0
- pydac3-3.0.0/src/pydac/config/cycle.py +255 -0
- pydac3-3.0.0/src/pydac/config/derivations.py +138 -0
- pydac3-3.0.0/src/pydac/config/errors.py +36 -0
- pydac3-3.0.0/src/pydac/config/execution.py +19 -0
- pydac3-3.0.0/src/pydac/config/input_help.py +138 -0
- pydac3-3.0.0/src/pydac/config/json_schema/experiment.schema.json +1019 -0
- pydac3-3.0.0/src/pydac/config/launch.py +37 -0
- pydac3-3.0.0/src/pydac/config/loader.py +593 -0
- pydac3-3.0.0/src/pydac/config/migrations.py +554 -0
- pydac3-3.0.0/src/pydac/config/model_validation.py +200 -0
- pydac3-3.0.0/src/pydac/config/nulls.py +103 -0
- pydac3-3.0.0/src/pydac/config/operating.py +127 -0
- pydac3-3.0.0/src/pydac/config/profile.py +78 -0
- pydac3-3.0.0/src/pydac/config/schema.py +448 -0
- pydac3-3.0.0/src/pydac/config/schema_generation.py +173 -0
- pydac3-3.0.0/src/pydac/config/sections.py +178 -0
- pydac3-3.0.0/src/pydac/config/serialization.py +58 -0
- pydac3-3.0.0/src/pydac/config/settings.py +156 -0
- pydac3-3.0.0/src/pydac/config/steps.py +265 -0
- pydac3-3.0.0/src/pydac/config/terminal.py +216 -0
- pydac3-3.0.0/src/pydac/config/validation.py +113 -0
- pydac3-3.0.0/src/pydac/core/TVSA_cycle.py +558 -0
- pydac3-3.0.0/src/pydac/core/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/core/bed_architectures/__init__.py +197 -0
- pydac3-3.0.0/src/pydac/core/bed_architectures/base.py +886 -0
- pydac3-3.0.0/src/pydac/core/bed_architectures/channeling.py +683 -0
- pydac3-3.0.0/src/pydac/core/bed_architectures/packed_bed.py +879 -0
- pydac3-3.0.0/src/pydac/core/column_model.py +2976 -0
- pydac3-3.0.0/src/pydac/core/column_model_factory.py +118 -0
- pydac3-3.0.0/src/pydac/core/column_model_input.py +82 -0
- pydac3-3.0.0/src/pydac/core/isotherm_models.py +942 -0
- pydac3-3.0.0/src/pydac/core/kinetic_models.py +155 -0
- pydac3-3.0.0/src/pydac/core/outlet_reporting.py +58 -0
- pydac3-3.0.0/src/pydac/core/pymrm_caching.py +487 -0
- pydac3-3.0.0/src/pydac/core/solver.py +742 -0
- pydac3-3.0.0/src/pydac/core/sparsity_patterns/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/core/sparsity_patterns/analytical_sparsity.py +293 -0
- pydac3-3.0.0/src/pydac/core/sparsity_patterns/numerical_sparsity.py +132 -0
- pydac3-3.0.0/src/pydac/core/species_catalog.py +206 -0
- pydac3-3.0.0/src/pydac/core/state_layout.py +530 -0
- pydac3-3.0.0/src/pydac/core/ternary_thermodynamics_separators.py +140 -0
- pydac3-3.0.0/src/pydac/core/thermodynamics_separators.py +120 -0
- pydac3-3.0.0/src/pydac/extensions.py +60 -0
- pydac3-3.0.0/src/pydac/inputs/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/inputs/case_io.py +378 -0
- pydac3-3.0.0/src/pydac/inputs/case_terminal.py +91 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/__init__.py +28 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/_rules.py +97 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/adsorption.py +87 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/column.py +138 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/execution.py +162 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/mixture.py +54 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/particle.py +116 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/profile.py +57 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/reference.py +31 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/solver.py +50 -0
- pydac3-3.0.0/src/pydac/inputs/defaults/steps.py +684 -0
- pydac3-3.0.0/src/pydac/post_processing/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/post_processing/context/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/post_processing/context/runtime_store.py +56 -0
- pydac3-3.0.0/src/pydac/post_processing/context/simulation_context.py +192 -0
- pydac3-3.0.0/src/pydac/post_processing/context/store.py +67 -0
- pydac3-3.0.0/src/pydac/post_processing/kpi/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/post_processing/kpi/cycle_kpis.py +1229 -0
- pydac3-3.0.0/src/pydac/post_processing/kpi/plotting.py +1160 -0
- pydac3-3.0.0/src/pydac/post_processing/kpi/reporting.py +962 -0
- pydac3-3.0.0/src/pydac/post_processing/metrics/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/post_processing/metrics/cycle_data.py +24 -0
- pydac3-3.0.0/src/pydac/post_processing/metrics/cycle_data_loader.py +265 -0
- pydac3-3.0.0/src/pydac/post_processing/metrics/cycle_metrics.py +303 -0
- pydac3-3.0.0/src/pydac/post_processing/metrics/step_metrics.py +304 -0
- pydac3-3.0.0/src/pydac/post_processing/metrics/step_metrics_store.py +121 -0
- pydac3-3.0.0/src/pydac/post_processing/optimization/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/post_processing/optimization/nsga2_post_processing.py +607 -0
- pydac3-3.0.0/src/pydac/post_processing/profiles/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/post_processing/profiles/cyclic_plotting.py +929 -0
- pydac3-3.0.0/src/pydac/post_processing/profiles/step_plotting.py +1757 -0
- pydac3-3.0.0/src/pydac/post_processing/profiles/step_post_processing.py +1722 -0
- pydac3-3.0.0/src/pydac/starter_kit.py +115 -0
- pydac3-3.0.0/src/pydac/utils/__init__.py +12 -0
- pydac3-3.0.0/src/pydac/utils/aspect_ratios.py +56 -0
- pydac3-3.0.0/src/pydac/utils/campaign.py +21 -0
- pydac3-3.0.0/src/pydac/utils/column/__init__.py +40 -0
- pydac3-3.0.0/src/pydac/utils/column/runtime_properties.py +147 -0
- pydac3-3.0.0/src/pydac/utils/column/validation.py +313 -0
- pydac3-3.0.0/src/pydac/utils/css/__init__.py +43 -0
- pydac3-3.0.0/src/pydac/utils/css/cycle.py +533 -0
- pydac3-3.0.0/src/pydac/utils/css/plotting.py +71 -0
- pydac3-3.0.0/src/pydac/utils/css/profiles.py +140 -0
- pydac3-3.0.0/src/pydac/utils/css/pruning.py +26 -0
- pydac3-3.0.0/src/pydac/utils/css/runner.py +273 -0
- pydac3-3.0.0/src/pydac/utils/flow_transforms.py +188 -0
- pydac3-3.0.0/src/pydac/utils/logger.py +76 -0
- pydac3-3.0.0/src/pydac/utils/model_registry.py +395 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/__init__.py +13 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/artifacts.py +73 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/checkpoint.py +621 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/decisions.py +121 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/evaluation.py +234 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/logging.py +660 -0
- pydac3-3.0.0/src/pydac/utils/nsga2/warm_start.py +316 -0
- pydac3-3.0.0/src/pydac/utils/plot_helpers.py +126 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/context_model.py +215 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/context_schema.py +452 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/cyclic_profiles.py +204 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/normalization.py +138 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/outlet.py +47 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/runtime_report.py +696 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/saved_solution.py +171 -0
- pydac3-3.0.0/src/pydac/utils/postprocessing/terminal_state.py +230 -0
- pydac3-3.0.0/src/pydac/utils/provenance.py +345 -0
- pydac3-3.0.0/src/pydac/utils/run/__init__.py +35 -0
- pydac3-3.0.0/src/pydac/utils/run/config.py +167 -0
- pydac3-3.0.0/src/pydac/utils/run/resume.py +272 -0
- pydac3-3.0.0/src/pydac/utils/run/steps.py +124 -0
- pydac3-3.0.0/src/pydac/utils/run/validation.py +263 -0
- pydac3-3.0.0/src/pydac/utils/solver/__init__.py +155 -0
- pydac3-3.0.0/src/pydac/utils/solver/composition_domain.py +138 -0
- pydac3-3.0.0/src/pydac/utils/solver/event_config.py +101 -0
- pydac3-3.0.0/src/pydac/utils/solver/events.py +390 -0
- pydac3-3.0.0/src/pydac/utils/solver/flags.py +26 -0
- pydac3-3.0.0/src/pydac/utils/solver/jacobian.py +28 -0
- pydac3-3.0.0/src/pydac/utils/solver/outcome.py +149 -0
- pydac3-3.0.0/src/pydac/utils/solver/oxygen_hot_bed_audit.py +511 -0
- pydac3-3.0.0/src/pydac/utils/solver/persistence.py +31 -0
- pydac3-3.0.0/src/pydac/utils/solver/pressure_plateau.py +128 -0
- pydac3-3.0.0/src/pydac/utils/solver/reporting.py +83 -0
- pydac3-3.0.0/src/pydac/utils/solver/sparsity.py +211 -0
- pydac3-3.0.0/src/pydac/utils/solver/species_balance.py +197 -0
- pydac3-3.0.0/src/pydac/utils/tvsa/__init__.py +77 -0
- pydac3-3.0.0/src/pydac/utils/tvsa/cycle_steps.py +58 -0
- pydac3-3.0.0/src/pydac/utils/tvsa/paths.py +87 -0
- pydac3-3.0.0/src/pydac/utils/tvsa/reporting.py +114 -0
- pydac3-3.0.0/src/pydac/utils/tvsa/steps.py +163 -0
- pydac3-3.0.0/src/pydac/utils/tvsa/termination.py +186 -0
- pydac3-3.0.0/src/pydac/utils/vector_drag.py +48 -0
- pydac3-3.0.0/src/pydac/utils/version.py +7 -0
- pydac3-3.0.0/src/pydac/workflows/__init__.py +1 -0
- pydac3-3.0.0/src/pydac/workflows/orchestrator_NSGA2.py +1532 -0
- pydac3-3.0.0/src/pydac/workflows/orchestrator_TVSA_cycle_css.py +409 -0
- pydac3-3.0.0/src/pydac/workflows/orchestrator_TVSA_steps.py +119 -0
- pydac3-3.0.0/tests/__init__.py +1 -0
- pydac3-3.0.0/tests/baselines/comparison_rules.json +40 -0
- pydac3-3.0.0/tests/baselines/hardcoding_inventory.json +324 -0
- pydac3-3.0.0/tests/baselines/v3_smoke_startup.json +270 -0
- pydac3-3.0.0/tests/cases/v3_smoke_startup.json +595 -0
- pydac3-3.0.0/tests/conftest.py +7 -0
- pydac3-3.0.0/tests/neutral_packed_bed.py +26 -0
- pydac3-3.0.0/tests/test_adsorption_registries.py +311 -0
- pydac3-3.0.0/tests/test_column_validation_utils.py +430 -0
- pydac3-3.0.0/tests/test_composition_domain_guard.py +181 -0
- pydac3-3.0.0/tests/test_energy_accumulation_source.py +174 -0
- pydac3-3.0.0/tests/test_energy_ledger_gate.py +358 -0
- pydac3-3.0.0/tests/test_export_settings.py +260 -0
- pydac3-3.0.0/tests/test_extensions.py +118 -0
- pydac3-3.0.0/tests/test_generic_configuration.py +397 -0
- pydac3-3.0.0/tests/test_initial_solid_loadings.py +255 -0
- pydac3-3.0.0/tests/test_inlet_flux_profile.py +126 -0
- pydac3-3.0.0/tests/test_moo_candidate_artifacts.py +253 -0
- pydac3-3.0.0/tests/test_moo_compact_persistence.py +292 -0
- pydac3-3.0.0/tests/test_moo_cooling_target_variable.py +130 -0
- pydac3-3.0.0/tests/test_moo_solver_failure_gate.py +407 -0
- pydac3-3.0.0/tests/test_moo_strong_resume.py +514 -0
- pydac3-3.0.0/tests/test_nsga2_campaigns.py +341 -0
- pydac3-3.0.0/tests/test_outlet_product_line.py +583 -0
- pydac3-3.0.0/tests/test_packed_bed_surface.py +86 -0
- pydac3-3.0.0/tests/test_phase0_baselines.py +159 -0
- pydac3-3.0.0/tests/test_phase5a_initialization.py +225 -0
- pydac3-3.0.0/tests/test_phase5b_rhs_solver_sparsity.py +327 -0
- pydac3-3.0.0/tests/test_phase6_postprocessing_runtime.py +492 -0
- pydac3-3.0.0/tests/test_phase6b_tier0_rhs.py +173 -0
- pydac3-3.0.0/tests/test_phase7_extension_example.py +105 -0
- pydac3-3.0.0/tests/test_profile_inventory_outlet.py +397 -0
- pydac3-3.0.0/tests/test_public_provenance.py +289 -0
- pydac3-3.0.0/tests/test_pydac_api_cli.py +940 -0
- pydac3-3.0.0/tests/test_release_reconciliation.py +105 -0
- pydac3-3.0.0/tests/test_runner_resume.py +284 -0
- pydac3-3.0.0/tests/test_sorbent_declarations.py +338 -0
- pydac3-3.0.0/tests/test_species_catalog.py +121 -0
- pydac3-3.0.0/tests/test_species_dispersion_correction.py +233 -0
- pydac3-3.0.0/tests/test_stable_drag_inversion.py +77 -0
- pydac3-3.0.0/tests/test_starter_kit.py +110 -0
- pydac3-3.0.0/tests/test_state_layout.py +249 -0
- pydac3-3.0.0/tests/test_termination_validation.py +127 -0
- pydac3-3.0.0/tests/test_vector_drag.py +91 -0
- pydac3-3.0.0/tests/test_wall_channeling_reduced.py +1183 -0
- pydac3-3.0.0/tests/tools/__init__.py +1 -0
- pydac3-3.0.0/tests/tools/generate_v3_smoke_baseline.py +203 -0
pydac3-3.0.0/.gitignore
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Python bytecode / cache
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
|
|
7
|
+
# Jupyter and IPython history
|
|
8
|
+
.ipynb_checkpoints/
|
|
9
|
+
*.ipynb~
|
|
10
|
+
|
|
11
|
+
# Local logs/output
|
|
12
|
+
*.log
|
|
13
|
+
*.tmp
|
|
14
|
+
*.bak
|
|
15
|
+
|
|
16
|
+
# Environment / virtualenvs (in case local)
|
|
17
|
+
.venv/
|
|
18
|
+
env/
|
|
19
|
+
venv/
|
|
20
|
+
|
|
21
|
+
# Mac/Windows/Linux system files
|
|
22
|
+
.DS_Store
|
|
23
|
+
Thumbs.db
|
|
24
|
+
|
|
25
|
+
# Test cache
|
|
26
|
+
.cache/
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
|
|
29
|
+
# Build artifacts
|
|
30
|
+
build/
|
|
31
|
+
dist/
|
|
32
|
+
*.egg-info/
|
|
33
|
+
|
|
34
|
+
# Simulation results
|
|
35
|
+
simulation_results/*
|
|
36
|
+
|
|
37
|
+
# Jacobian masks are generated in memory; no cache folder may come back
|
|
38
|
+
src/pydac/core/sparsity_patterns/*/
|
|
39
|
+
|
|
40
|
+
.vscode/
|
|
41
|
+
|
|
42
|
+
# Run folders and saved files written by the tutorials (from any folder)
|
|
43
|
+
examples/**/simulation_results/
|
|
44
|
+
output_cases/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Citation metadata. At each GitHub release Zenodo adds the DOI and the release date;
|
|
2
|
+
# the paper becomes `preferred-citation` once it is published.
|
|
3
|
+
cff-version: 1.2.0
|
|
4
|
+
message: "If you use pyDAC in your research, please cite it as below."
|
|
5
|
+
title: "pyDAC: simulation of adsorption-based direct air capture processes"
|
|
6
|
+
type: software
|
|
7
|
+
authors:
|
|
8
|
+
- given-names: Mattia
|
|
9
|
+
family-names: Galanti
|
|
10
|
+
- given-names: Ivo
|
|
11
|
+
family-names: Roghair
|
|
12
|
+
- given-names: Martin
|
|
13
|
+
name-particle: van
|
|
14
|
+
family-names: Sint Annaland
|
|
15
|
+
license: MIT
|
|
16
|
+
version: 3.0.0
|
|
17
|
+
repository-code: "https://github.com/process-intensification-lab/pyDAC"
|
|
18
|
+
keywords:
|
|
19
|
+
- direct air capture
|
|
20
|
+
- adsorption
|
|
21
|
+
- TVSA
|
|
22
|
+
- cyclic adsorption
|
|
23
|
+
- packed bed
|
|
24
|
+
- process simulation
|
|
25
|
+
abstract: >-
|
|
26
|
+
pyDAC simulates adsorption cycles composed from configurable steps (by default a
|
|
27
|
+
steam-assisted temperature-vacuum swing adsorption, TVSA, cycle) for CO2 direct air capture
|
|
28
|
+
in 1D and 2D packed beds: single step sequences, cycles to cyclic steady state with KPIs, and
|
|
29
|
+
local NSGA-II optimization of the operating conditions.
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Contributing to pyDAC
|
|
2
|
+
|
|
3
|
+
This page is for developers working in a clone of the repository. To use pyDAC, read
|
|
4
|
+
[`README.md`](README.md) instead. Rules come first, each with its reason in one line.
|
|
5
|
+
|
|
6
|
+
## Using pyDAC or changing it
|
|
7
|
+
|
|
8
|
+
| You want to | Install | Which code runs |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| use pyDAC | `python -m pip install pydac3` ([README](README.md#2-install-pydac)) | a copy fixed at install time; files you edit are not used |
|
|
11
|
+
| change pyDAC | a clone, installed editable (`python -m pip install -e .`) | the clone's `src/pydac/`: an edit is used at the next import |
|
|
12
|
+
|
|
13
|
+
An editable install copies no code: it points the environment at the clone. Everything
|
|
14
|
+
below is about the second row.
|
|
15
|
+
|
|
16
|
+
## Environment
|
|
17
|
+
|
|
18
|
+
- **One dedicated environment per clone, never shared between clones.** An editable
|
|
19
|
+
install points the environment at one clone; a second clone in the same environment
|
|
20
|
+
silently runs the first one's code.
|
|
21
|
+
- **Disable the user site.** Packages under `~/.local` shadow the environment's own
|
|
22
|
+
numpy, scipy and pandas: set `PYTHONNOUSERSITE=1` in the shell that runs pyDAC.
|
|
23
|
+
- **Pick the light or the exact environment.** The light one takes the newest allowed
|
|
24
|
+
version of every dependency and works with any supported Python; the exact one is the
|
|
25
|
+
qualification lock, the only one in which your numbers match the qualified ones digit
|
|
26
|
+
for digit and the `qualification` tests hold.
|
|
27
|
+
|
|
28
|
+
Get the code: fork the repository on GitHub (if you plan to propose changes) and clone
|
|
29
|
+
your fork:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/<your-user>/pyDAC.git
|
|
33
|
+
cd pyDAC
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Light environment**, from the root of the clone, with Python 3.11 to 3.14:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export PYTHONNOUSERSITE=1
|
|
40
|
+
python -m venv .venv
|
|
41
|
+
source .venv/bin/activate
|
|
42
|
+
python -m pip install --upgrade pip
|
|
43
|
+
python -m pip install -e .
|
|
44
|
+
python -m pip install --group test
|
|
45
|
+
python -m pip check
|
|
46
|
+
python -c "import site, pydac; print(site.ENABLE_USER_SITE, pydac.__file__)"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Exact environment**, from the root of the clone, with Python 3.12 (the lock is written
|
|
50
|
+
for it):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
export PYTHONNOUSERSITE=1
|
|
54
|
+
python3.12 -m venv .venv
|
|
55
|
+
source .venv/bin/activate
|
|
56
|
+
python -m pip install --require-hashes -r ci/qualification-lock-py3.12.txt
|
|
57
|
+
python -m pip install --no-deps -e .
|
|
58
|
+
python -m pip check
|
|
59
|
+
python -c "import site, pydac; print(site.ENABLE_USER_SITE, pydac.__file__)"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
In both, the last line must print `False` and a path inside this clone's `src/pydac/`.
|
|
63
|
+
The name `.venv` is the one VS Code detects on its own. The lock already holds pytest.
|
|
64
|
+
|
|
65
|
+
- **Restart running Python sessions after editing sources.** An editable install reads
|
|
66
|
+
the sources when a module is first imported; a running interpreter or notebook kernel
|
|
67
|
+
keeps the old code until it restarts.
|
|
68
|
+
- **Reinstall after changing `pyproject.toml`** (dependencies, entry points, metadata):
|
|
69
|
+
run `python -m pip install --no-deps -e .` again. Until then the installed metadata is
|
|
70
|
+
stale, which is why `importlib.metadata.version("pydac3")` is never used as the
|
|
71
|
+
version.
|
|
72
|
+
|
|
73
|
+
## What is supported
|
|
74
|
+
|
|
75
|
+
| Level | What | Promise |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| Command | `pydac steps`, `pydac css`, `pydac nsga2`, `pydac validate` and their flags | documented; changes announced in the release notes |
|
|
78
|
+
| API | the names in `pydac.__all__` | documented; changes announced in the release notes |
|
|
79
|
+
| Internal | every other module under `src/pydac/` | shipped and importable, no stability promise |
|
|
80
|
+
| Clone tools | `runners/`, `tests/`, `docs/`, `ci/` | for working in a clone; not in the wheel |
|
|
81
|
+
|
|
82
|
+
User documentation shows only commands and `pydac.__all__` names.
|
|
83
|
+
|
|
84
|
+
## Running from VS Code
|
|
85
|
+
|
|
86
|
+
The files in [`runners/`](runners/) are launchers for this clone; they are not shipped in
|
|
87
|
+
the wheel. The step, CSS and campaign runners call the `pydac` command with the constants
|
|
88
|
+
at their top; `validate_config.py` has no constants and passes its command-line arguments
|
|
89
|
+
to `pydac validate`:
|
|
90
|
+
|
|
91
|
+
| Runner | Same as |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `runners/run_steps_simulation.py` | `pydac steps` |
|
|
94
|
+
| `runners/run_css_simulation.py` | `pydac css` |
|
|
95
|
+
| `runners/run_NSGA2.py` | `pydac nsga2` |
|
|
96
|
+
| `runners/validate_config.py` | `pydac validate` |
|
|
97
|
+
|
|
98
|
+
| Constant | Effect |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `CONFIG_PATH` | a partial preset, as `--config` |
|
|
101
|
+
| `DEVELOPMENT_SETTINGS` | settings applied after the preset and before `--set` |
|
|
102
|
+
| `CASE_PATH` | a complete case run exactly, as `--case` |
|
|
103
|
+
| `RESUME_PATH` | a saved run to continue, as `--resume` |
|
|
104
|
+
| `OVERWRITE` | replace this case's existing run folder, as `--overwrite` (step and CSS runners only) |
|
|
105
|
+
|
|
106
|
+
- Precedence: built-in defaults < `CONFIG_PATH` (or `--config`) < `DEVELOPMENT_SETTINGS`
|
|
107
|
+
< `--set`. `pydac` itself never reads these constants; only the runner passes them.
|
|
108
|
+
- `CASE_PATH` refuses `CONFIG_PATH`, `--config`, `--set` and non-empty
|
|
109
|
+
`DEVELOPMENT_SETTINGS`: a frozen case runs exactly as saved.
|
|
110
|
+
- Running the same case twice is refused (exit code `2`) while its run folder exists:
|
|
111
|
+
set `OVERWRITE = True`, resume it, or change `execution.extra_tag`. A campaign has no
|
|
112
|
+
`OVERWRITE`: continue it with `RESUME_PATH`, or delete its folder yourself.
|
|
113
|
+
- A CSS (cyclic steady state) run that stops at `execution.max_cycles` without reaching CSS exits with code
|
|
114
|
+
`3` when `execution.require_css` is true. Errors go to stderr.
|
|
115
|
+
- Select this clone's `.venv` as the VS Code interpreter.
|
|
116
|
+
|
|
117
|
+
## Tests
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
python -m pytest -q -m "not qualification"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The light environment installs pytest with `--group test`, which needs pip 25.1 or
|
|
124
|
+
newer. Tests marked `qualification` compare fingerprints and numbers that hold only in
|
|
125
|
+
the exact environment; inside it, run the full suite with `python -m pytest -q`.
|
|
126
|
+
|
|
127
|
+
## Proposing a change
|
|
128
|
+
|
|
129
|
+
- **Open an issue before the code** for anything beyond a small fix: say what you want to
|
|
130
|
+
change and why. A change to the physics core needs the maintainer's agreement first
|
|
131
|
+
([below](#physics-core-maintainer-review)).
|
|
132
|
+
- **One topic per pull request, on its own branch** of your fork, started from `main`:
|
|
133
|
+
a reviewer can then accept or refuse each change on its own.
|
|
134
|
+
- **Run the checks in your clone before opening the pull request:**
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
python -m pytest -q -m "not qualification"
|
|
138
|
+
python docs/check_links.py
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
New behaviour comes with a test that fails without it.
|
|
142
|
+
- **Open the pull request against `main`.** CI builds the wheel, installs it on Linux
|
|
143
|
+
(Python 3.11 to 3.14) and on Windows, runs the tests, a short run of the `pydac`
|
|
144
|
+
command and the link check. A pull request is merged with CI green and the
|
|
145
|
+
maintainer's review.
|
|
146
|
+
- **Say in the pull request whether results change, and which cases you compared.** The
|
|
147
|
+
`qualification` job of CI fails when numbers move; a change that moves them on purpose
|
|
148
|
+
needs the reason, and the maintainer regenerates the baseline.
|
|
149
|
+
- **Keep the documentation in step.** A change to a command, a setting or a
|
|
150
|
+
`pydac.__all__` name updates the guide or the manual in the same pull request, and its
|
|
151
|
+
description says what users will notice, for the release notes.
|
|
152
|
+
|
|
153
|
+
## Code rules
|
|
154
|
+
|
|
155
|
+
- **Absolute imports only:** `from pydac.config import ...`. No `sys.path` edits and no
|
|
156
|
+
imports of `src.` or of top-level folders; with the `src/` layout, `import pydac` works
|
|
157
|
+
from a clone only through the editable install.
|
|
158
|
+
- **No formatter or linter pass.** A formatting pass rewrites every line of the physics
|
|
159
|
+
files, which would hide the physical changes under review; do not reformat code you do
|
|
160
|
+
not change.
|
|
161
|
+
- **Code headers cite reference sections** (`# Guide: docs/manual/01_inputs.md §3`), and
|
|
162
|
+
`docs/check_links.py` checks them. When you renumber or move a section, update every
|
|
163
|
+
header that cites it.
|
|
164
|
+
- **Plain words in code and messages.** Write what a rule does, not an internal decision
|
|
165
|
+
label.
|
|
166
|
+
|
|
167
|
+
## Physics core: maintainer review
|
|
168
|
+
|
|
169
|
+
Changes to [`src/pydac/core/column_model.py`](src/pydac/core/column_model.py) and to
|
|
170
|
+
anything under [`src/pydac/post_processing/`](src/pydac/post_processing/) need the
|
|
171
|
+
maintainer's review before they are written: open an issue that states what you intend
|
|
172
|
+
to change, why (the physical or numerical reasoning) and the expected effect on results.
|
|
173
|
+
These files define what pyDAC computes and reports.
|
|
174
|
+
|
|
175
|
+
## Extending the model
|
|
176
|
+
|
|
177
|
+
An isotherm or a kinetic law of your own can be used without changing pyDAC: register it from
|
|
178
|
+
Python ([Extending pyDAC](docs/guide/08_extending.md)). Adding one to the package, so that
|
|
179
|
+
every user and the `pydac` command know it, or adding a species, is code work in a clone;
|
|
180
|
+
pull requests are welcome. The contract each addition must meet is in
|
|
181
|
+
[`docs/manual/01_inputs.md` §10](docs/manual/01_inputs.md#10-extending-the-contract):
|
|
182
|
+
|
|
183
|
+
- **Species:** a `SpeciesProperties` entry in
|
|
184
|
+
[`src/pydac/core/species_catalog.py`](src/pydac/core/species_catalog.py) (molar mass,
|
|
185
|
+
Lennard-Jones parameters, Fuller volume, conductivity and Shomate heat-capacity
|
|
186
|
+
coefficients).
|
|
187
|
+
- **Isotherm:** an entry in `EQUILIBRIUM_REGISTRY` in
|
|
188
|
+
[`src/pydac/core/isotherm_models.py`](src/pydac/core/isotherm_models.py).
|
|
189
|
+
- **Kinetic model:** an entry in `KINETIC_REGISTRY` in
|
|
190
|
+
[`src/pydac/core/kinetic_models.py`](src/pydac/core/kinetic_models.py).
|
|
191
|
+
|
|
192
|
+
The built-in registries, the species catalog and the bed-architecture registry are read-only
|
|
193
|
+
at run time. `pydac.register_equilibrium` and `pydac.register_kinetics` add models for one
|
|
194
|
+
Python session only, beside the built-in ones, and refuse a built-in name.
|
|
195
|
+
|
|
196
|
+
## Saved files and versions
|
|
197
|
+
|
|
198
|
+
- A change to the shape of a saved file (case, run folder records, campaign checkpoint)
|
|
199
|
+
bumps that file's version number.
|
|
200
|
+
- Readers keep accepting every older version; a newer version than the reader knows is
|
|
201
|
+
refused with a message naming the file.
|
|
202
|
+
- A new case field needs a case-schema version bump and an upgrade step that gives
|
|
203
|
+
older cases the value reproducing what they computed
|
|
204
|
+
([`src/pydac/config/migrations.py`](src/pydac/config/migrations.py)).
|
|
205
|
+
- From a later release on, each release will add a small set of frozen saved files under
|
|
206
|
+
`tests/data/`, with a test that the installed package reads, reports, replays and
|
|
207
|
+
continues them.
|
|
208
|
+
|
|
209
|
+
## Dependency pins
|
|
210
|
+
|
|
211
|
+
`pymrm` is pinned exactly (`pymrm==2.1.10`) because pyDAC calls internals of it that
|
|
212
|
+
changed after that version; `scikit-sundae` is held to 1.1.x and `pandas` below 3.
|
|
213
|
+
Raising any of these is a release decision: rerun the qualified cases in the new
|
|
214
|
+
environment and compare them with the current results first.
|
|
215
|
+
|
|
216
|
+
## Tools
|
|
217
|
+
|
|
218
|
+
| Task | Command |
|
|
219
|
+
|---|---|
|
|
220
|
+
| Regenerate the JSON schema of the case document after changing a default or rule | `python -m pydac.config.schema_generation` |
|
|
221
|
+
| Draw the analytical Jacobian sparsity mask | `python -m pydac.core.sparsity_patterns.analytical_sparsity --nz 10 --nr 5 --out FOLDER` |
|
|
222
|
+
| Check a step's recorded Jacobians against the analytical mask | `python -m pydac.core.sparsity_patterns.numerical_sparsity FOLDER --nz 10 --nr 5` |
|
|
223
|
+
| Check documentation links and code `# Guide:` headers | `python docs/check_links.py` |
|
|
224
|
+
| Regenerate the smoke-test baseline (qualification environment only) | `python tests/tools/generate_v3_smoke_baseline.py` |
|
|
225
|
+
|
|
226
|
+
Environment variables for developers (do not set them for production runs). The two
|
|
227
|
+
solver switches are recorded in each run's provenance (`software.solver_environment`); the
|
|
228
|
+
other two are not:
|
|
229
|
+
|
|
230
|
+
| Variable | Effect |
|
|
231
|
+
|---|---|
|
|
232
|
+
| `PYDAC_NO_ENV_WARNING=1` | silences the dedicated-environment warning of the `pydac` command |
|
|
233
|
+
| `PYDAC_PROFILE=PATH` | replaces the built-in defaults with a complete JSON profile |
|
|
234
|
+
| `PYDAC_RHS_CSR_OPERATORS=0` | applies the fixed operators in their original sparse format (A/B checks) |
|
|
235
|
+
| `PYDAC_CACHE_SLICE_WRITE=0` | disables the contiguous-slice writes of the operator cache (A/B checks) |
|
|
236
|
+
|
|
237
|
+
## Releases
|
|
238
|
+
|
|
239
|
+
- The version lives in one place, `src/pydac/utils/version.py`.
|
|
240
|
+
- A published tag is never moved or re-created; a fix is a new version.
|
pydac3-3.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mattia Galanti, Ivo Roghair, Martin van Sint Annaland
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pydac3-3.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pydac3
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: Simulation of adsorption-based direct air capture processes.
|
|
5
|
+
Project-URL: Repository, https://github.com/process-intensification-lab/pyDAC
|
|
6
|
+
Project-URL: Issues, https://github.com/process-intensification-lab/pyDAC/issues
|
|
7
|
+
Author: Mattia Galanti, Ivo Roghair, Martin van Sint Annaland
|
|
8
|
+
Maintainer-email: Mattia Galanti <mattiagalanti1@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: TVSA,adsorption,cyclic adsorption,direct air capture,packed bed,process simulation
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: matplotlib>=3.8.1
|
|
24
|
+
Requires-Dist: numpy>=1.26.4
|
|
25
|
+
Requires-Dist: pandas<3,>=2.2
|
|
26
|
+
Requires-Dist: pymoo>=0.6.2
|
|
27
|
+
Requires-Dist: pymrm==2.1.10
|
|
28
|
+
Requires-Dist: scikit-sundae<1.2,>=1.1
|
|
29
|
+
Requires-Dist: scipy>=1.13.1
|
|
30
|
+
Requires-Dist: seaborn>=0.13
|
|
31
|
+
Provides-Extra: all
|
|
32
|
+
Requires-Dist: argcomplete; extra == 'all'
|
|
33
|
+
Provides-Extra: completion
|
|
34
|
+
Requires-Dist: argcomplete; extra == 'completion'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# pyDAC
|
|
38
|
+
|
|
39
|
+
pyDAC simulates adsorption-based direct air capture (DAC) processes. It solves the
|
|
40
|
+
coupled mass, energy and momentum balances of a sorbent column in 1D or 2D
|
|
41
|
+
(axisymmetric) and runs adsorption cycles step by step or to cyclic steady state (CSS).
|
|
42
|
+
A cycle is composed from configurable steps (adsorption, blowdown, heating, purge, steam-
|
|
43
|
+
or wall-heated desorption, cooling, pressurization); the default is a steam-assisted
|
|
44
|
+
temperature-vacuum swing adsorption (TVSA) cycle. pyDAC reports process key performance
|
|
45
|
+
indicators (KPIs) and optimizes operating conditions with the NSGA-II genetic algorithm
|
|
46
|
+
(non-dominated sorting genetic algorithm II).
|
|
47
|
+
|
|
48
|
+
pyDAC 3.0.0, development status Beta. MIT license.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
### 1. Create a dedicated environment
|
|
53
|
+
|
|
54
|
+
Install pyDAC in an environment of its own: never in the system Python, a conda `base`
|
|
55
|
+
environment, or an environment shared with other projects. pyDAC fixes the versions of
|
|
56
|
+
some dependencies (`pymrm==2.1.10`, `pandas<3`, `scikit-sundae` 1.1.x), and pip silently
|
|
57
|
+
replaces versions that are already installed, so a shared environment can break pyDAC
|
|
58
|
+
or the other project without any message.
|
|
59
|
+
|
|
60
|
+
Linux, with `venv`:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
python3 -m venv pydac-env
|
|
64
|
+
source pydac-env/bin/activate
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Windows (PowerShell), with `venv`:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
py -m venv pydac-env
|
|
71
|
+
pydac-env\Scripts\Activate.ps1
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
With conda instead:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
conda create -n pydac python=3.12
|
|
78
|
+
conda activate pydac
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
With uv instead (`uv` environments have no `pip`; write `uv pip` where this page writes
|
|
82
|
+
`python -m pip`):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv venv pydac-env
|
|
86
|
+
source pydac-env/bin/activate
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2. Install pyDAC
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
python -m pip install pydac3
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The distribution is called `pydac3`; the package you import and the command you run are
|
|
96
|
+
both `pydac`. `pip install pydac` installs an unrelated project.
|
|
97
|
+
|
|
98
|
+
One install contains everything: step runs, CSS runs, case validation and NSGA-II
|
|
99
|
+
optimization (pymoo is a regular dependency). `pydac get-started my_pydac` copies the tutorials
|
|
100
|
+
and the user guide into a new folder
|
|
101
|
+
([Get the tutorials](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/01_installation.md#get-the-tutorials-and-this-guide)). The optional extra `completion` adds shell
|
|
102
|
+
completion for the `pydac` command (`python -m pip install "pydac3[completion]"`).
|
|
103
|
+
|
|
104
|
+
Python 3.11 to 3.14 on Linux (x86_64) is supported. Windows is being tested; macOS is
|
|
105
|
+
neither tested nor supported.
|
|
106
|
+
|
|
107
|
+
**Want to adapt pyDAC to your own needs, or help improve it?** Install it from a clone in
|
|
108
|
+
editable mode instead; then an edit in `src/pydac/` is used at the next import:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git clone https://github.com/process-intensification-lab/pyDAC.git
|
|
112
|
+
cd pyDAC
|
|
113
|
+
python -m pip install -e .
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
[`CONTRIBUTING.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/CONTRIBUTING.md) gives the full procedure (dedicated environment, light or
|
|
117
|
+
exact dependencies, tests) and how to propose a change.
|
|
118
|
+
|
|
119
|
+
### 3. Check the environment
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
python -m pip check
|
|
123
|
+
pydac --version
|
|
124
|
+
python -c "import pydac; print(pydac.__file__)"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`pip check` must report no broken requirements, and the printed path must lie inside
|
|
128
|
+
the environment you created. A path in the user site instead (for example under
|
|
129
|
+
`~/.local/lib/`) means a user-site installation shadows the environment; set
|
|
130
|
+
`PYTHONNOUSERSITE=1` or remove that installation.
|
|
131
|
+
|
|
132
|
+
When the `pydac` command runs outside a virtual environment or a conda environment
|
|
133
|
+
other than `base`, it prints a one-line warning on stderr and continues. Set
|
|
134
|
+
`PYDAC_NO_ENV_WARNING=1` to silence it, for example in a container that uses the system
|
|
135
|
+
Python on purpose. `import pydac` never prints it.
|
|
136
|
+
|
|
137
|
+
### Exact reproduction
|
|
138
|
+
|
|
139
|
+
To reproduce the qualified environment exactly (every package pinned, with hashes;
|
|
140
|
+
Python 3.12), install from the lock file into a second fresh environment, from the
|
|
141
|
+
root of a clone:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
python3.12 -m venv pydac-exact
|
|
145
|
+
source pydac-exact/bin/activate
|
|
146
|
+
python -m pip install --require-hashes -r ci/qualification-lock-py3.12.txt
|
|
147
|
+
python -m pip install --no-deps .
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Tutorials
|
|
151
|
+
|
|
152
|
+
**The best way to learn pyDAC is the seven tutorials. Start with
|
|
153
|
+
[01 First steps](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/01_first_steps.ipynb)**, then follow them in order.
|
|
154
|
+
`pydac get-started my_pydac` copies them, with the user guide, into a new folder. Each
|
|
155
|
+
tutorial is a notebook and states its runtime (from a few minutes to about 40). Tutorials
|
|
156
|
+
01-06 also run from the terminal, with the commands in [`examples/README.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/README.md);
|
|
157
|
+
tutorial 07 needs Python, because it registers its own isotherm.
|
|
158
|
+
|
|
159
|
+
| Tutorial | What it shows |
|
|
160
|
+
|---|---|
|
|
161
|
+
| [01 First steps](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/01_first_steps.ipynb) | a step run, the KPI table of each step, step profile plots, time- or event-based stop |
|
|
162
|
+
| [02 Build your own case](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/02_custom_case.ipynb) | replace the defaults block by block (column, gas, sorbent, isotherm, kinetics, steps); a 2D TSA step run |
|
|
163
|
+
| [03 A cycle at its periodic state](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/03_css_tvsa.ipynb) | a CSS run of the built-in TVSA cycle in 2D, the cycle KPIs, where the CO2 and the energy go |
|
|
164
|
+
| [04 1D or 2D](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/04_1d_vs_2d.ipynb) | the same cycle in 1D, in 2D and in 2D with wall channeling |
|
|
165
|
+
| [05 An optimization campaign](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/05_nsga2_trial.ipynb) | a trial NSGA-II campaign: variables, bounds, constraints, the Pareto front |
|
|
166
|
+
| [06 Reproduce the breakthrough validation](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/06_breakthrough_validation.ipynb) | the 2D model of the pyDAC paper against the measurements of Zanco et al. |
|
|
167
|
+
| [07 Your own isotherm](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/notebooks/07_new_isotherm.ipynb) | a new sorbent from the literature, its isotherm registered from Python and run |
|
|
168
|
+
|
|
169
|
+
## Quick start from the terminal
|
|
170
|
+
|
|
171
|
+
A case is the complete set of inputs of one simulation. Write the built-in case to a
|
|
172
|
+
file, here with a coarse 1D grid and at most three cycles:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
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
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`my_case.json` holds every input of the simulation. To change it, prefer settings over
|
|
179
|
+
editing the file: they recompute the fields that depend on others, such as the bed length
|
|
180
|
+
from its volume ([Cases and settings](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/03_cases.md)). Then run it exactly as
|
|
181
|
+
saved; it repeats the cycle until cyclic steady state, here for at most three cycles;
|
|
182
|
+
this coarse case reaches CSS at cycle 3:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pydac css --case my_case.json
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The run takes one to two minutes. It writes everything under
|
|
189
|
+
`simulation_results/cyclic_mode/packed_bed_XXXXXXXX/`, where `XXXXXXXX` is the start of
|
|
190
|
+
the case fingerprint, and prints that run folder as its last line. Inside,
|
|
191
|
+
`1D_mode/cycle_N/` holds each cycle and `1D_mode/kpis/` the KPI tables of the final
|
|
192
|
+
cycle. Running the same case again is refused while that folder exists: continue it with
|
|
193
|
+
`--resume`, replace it with `--overwrite`, or set another `execution.extra_tag`.
|
|
194
|
+
|
|
195
|
+
The other commands are `pydac steps` (startup, then each listed step once),
|
|
196
|
+
`pydac nsga2` (an optimization campaign) and `pydac validate`. Each lists its options
|
|
197
|
+
with `--help`; `pydac validate --show-settings` lists the settings with their built-in
|
|
198
|
+
defaults. Instead of a complete case, `--config` takes a partial preset whose omitted
|
|
199
|
+
fields take the built-in defaults, for example
|
|
200
|
+
[`examples/cases/quick_1D.json`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/examples/cases/quick_1D.json) from the repository:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pydac css --config examples/cases/quick_1D.json --dry-run
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Exit codes: `0` success, `1` failure after the run started, `2` invalid command-line
|
|
207
|
+
arguments, configuration error or refused request, `3` CSS not reached while
|
|
208
|
+
`execution.require_css` is true.
|
|
209
|
+
|
|
210
|
+
## Quick start from Python
|
|
211
|
+
|
|
212
|
+
The same steps through the Python API, in a script or a notebook. This loads the saved
|
|
213
|
+
case, changes one setting, runs it and reads two KPIs:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
import pydac
|
|
217
|
+
|
|
218
|
+
case = pydac.load_case("my_case.json", settings={"execution.max_cycles": 4})
|
|
219
|
+
result = pydac.run_css(case)
|
|
220
|
+
print(result.folder, result.css_reached, result.cycle)
|
|
221
|
+
|
|
222
|
+
kpis = pydac.CycleKPIs(pydac.CycleDataLoader(result.folder).load())
|
|
223
|
+
print(f"CO2 recovery: {100 * kpis.recovery('CO2'):.1f} %")
|
|
224
|
+
print(f"Productivity: {kpis.productivity():.2f} kg CO2 per m3 bed per day")
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`pydac.load_case(path, exact=True)` runs a complete case exactly, as `--case` does. The
|
|
228
|
+
supported API is the set of names in `pydac.__all__`: `load_case`, `export_case`,
|
|
229
|
+
`export_settings`, `run_steps`, `run_css`, `run_nsga2`, `resume`, `report`, `get_started`,
|
|
230
|
+
`RunResult`, `ConfigurationError`, `RunRefused`, `ExperimentConfig`, `CycleDataLoader`,
|
|
231
|
+
`CycleKPIs`, `register_equilibrium`, `register_kinetics`, `EquilibriumSystem`, `KineticLaw`,
|
|
232
|
+
`EquilibriumRegistryEntry`, `KineticRegistryEntry` and the version string `__version__`.
|
|
233
|
+
|
|
234
|
+
## Reproducibility
|
|
235
|
+
|
|
236
|
+
Every run folder contains the resolved case (`resolved_config.json`), its fingerprint
|
|
237
|
+
(`case_metadata.json`) and a provenance record: the pyDAC version, the Python version,
|
|
238
|
+
the platform and the versions of the numerical dependencies. Run from a clone, the
|
|
239
|
+
record also says whether the checkout had uncommitted changes; it does not record the Git
|
|
240
|
+
revision, so keep the commit of an unreleased checkout yourself. To
|
|
241
|
+
rerun a result, run its `resolved_config.json` with `--case` (in another output root, or
|
|
242
|
+
with `--overwrite`); to rebuild the environment, use the lock file above.
|
|
243
|
+
|
|
244
|
+
## Documentation
|
|
245
|
+
|
|
246
|
+
Read in this order: the tutorials (above) teach pyDAC on real runs; the user guide is
|
|
247
|
+
the reference for using it, in more technical detail; the reference manual describes how pyDAC
|
|
248
|
+
works inside, in full technical detail, for contributors and for checking the model. The
|
|
249
|
+
documentation index is [`docs/README.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/README.md). The user guide explains how to use
|
|
250
|
+
pyDAC:
|
|
251
|
+
|
|
252
|
+
- [Installation](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/01_installation.md): environments, Jupyter, shell
|
|
253
|
+
completion, exact reproduction, troubleshooting.
|
|
254
|
+
- [Quick start](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/02_quickstart.md): one case from the terminal, a script
|
|
255
|
+
and a notebook; the Python API and its errors.
|
|
256
|
+
- [Cases and settings](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/03_cases.md): presets, settings, frozen cases,
|
|
257
|
+
model choices, `null`, fingerprints.
|
|
258
|
+
- [Running steps and cycles](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/04_running.md): step sequence, stop rules,
|
|
259
|
+
resume, replay, report, run folders, exit codes.
|
|
260
|
+
- [Optimization campaigns](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/05_optimization.md): NSGA-II campaigns, bounds,
|
|
261
|
+
constraints, stop rules, continuing and reporting a campaign.
|
|
262
|
+
- [Results](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/06_results.md): run folders, KPI files, reading results from
|
|
263
|
+
Python, which folders to trust.
|
|
264
|
+
- [Reproducibility](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/07_reproducibility.md): sharing a case, provenance,
|
|
265
|
+
the exact environment, compatibility across versions.
|
|
266
|
+
- [Extending pyDAC](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/guide/08_extending.md): your own isotherms and kinetic laws,
|
|
267
|
+
registered from Python; what needs a change to the package.
|
|
268
|
+
|
|
269
|
+
The reference chapters describe the model and the code:
|
|
270
|
+
|
|
271
|
+
| Chapter | Contents |
|
|
272
|
+
|---|---|
|
|
273
|
+
| [`00_framework_map.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/00_framework_map.md) | Layers, entry points and what a run does end to end |
|
|
274
|
+
| [`01_inputs.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/01_inputs.md) | Cases, presets, settings and the case document |
|
|
275
|
+
| [`02_pydac_core.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/02_pydac_core.md) | Model construction, state vector, solver and cycle orchestration |
|
|
276
|
+
| [`03_pymrm_discretization.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/03_pymrm_discretization.md) | Finite-volume operators and boundary conditions |
|
|
277
|
+
| [`04_governing_equations.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/04_governing_equations.md) | Balances and closures, and where the code assembles them |
|
|
278
|
+
| [`05_cycle_steps.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/05_cycle_steps.md) | Each cycle step: physics, boundary conditions, stop rules |
|
|
279
|
+
| [`06_post_processing.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/06_post_processing.md) | KPIs, separators, plots and result files |
|
|
280
|
+
| [`07_nsga2_optimization.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/docs/manual/07_nsga2_optimization.md) | NSGA-II campaigns |
|
|
281
|
+
|
|
282
|
+
To work on pyDAC itself, read [`CONTRIBUTING.md`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/CONTRIBUTING.md).
|
|
283
|
+
|
|
284
|
+
## How to cite
|
|
285
|
+
|
|
286
|
+
If you use pyDAC in your research, please cite it with the metadata in
|
|
287
|
+
[`CITATION.cff`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/CITATION.cff). Each GitHub release has its own DOI on Zenodo; once the
|
|
288
|
+
pyDAC paper is published, it becomes the preferred citation.
|
|
289
|
+
|
|
290
|
+
## License and authors
|
|
291
|
+
|
|
292
|
+
pyDAC is released under the MIT license ([`LICENSE`](https://github.com/process-intensification-lab/pyDAC/blob/v3.0.0/LICENSE)). Authors: Mattia
|
|
293
|
+
Galanti, Ivo Roghair and Martin van Sint Annaland (Eindhoven University of Technology).
|
|
294
|
+
Maintainer: Mattia Galanti.
|
|
295
|
+
|
|
296
|
+
## Acknowledgements
|
|
297
|
+
|
|
298
|
+
We thank Shell Global Solutions International BV for financial support.
|