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.
Files changed (251) hide show
  1. pydac3-3.0.0/.gitignore +44 -0
  2. pydac3-3.0.0/CITATION.cff +29 -0
  3. pydac3-3.0.0/CONTRIBUTING.md +240 -0
  4. pydac3-3.0.0/LICENSE +21 -0
  5. pydac3-3.0.0/PKG-INFO +298 -0
  6. pydac3-3.0.0/README.md +262 -0
  7. pydac3-3.0.0/ci/qualification-lock-py3.12.txt +2049 -0
  8. pydac3-3.0.0/docs/.gitignore +2 -0
  9. pydac3-3.0.0/docs/README.md +57 -0
  10. pydac3-3.0.0/docs/check_links.py +139 -0
  11. pydac3-3.0.0/docs/guide/01_installation.md +244 -0
  12. pydac3-3.0.0/docs/guide/02_quickstart.md +255 -0
  13. pydac3-3.0.0/docs/guide/03_cases.md +287 -0
  14. pydac3-3.0.0/docs/guide/04_running.md +311 -0
  15. pydac3-3.0.0/docs/guide/05_optimization.md +306 -0
  16. pydac3-3.0.0/docs/guide/06_results.md +287 -0
  17. pydac3-3.0.0/docs/guide/07_reproducibility.md +133 -0
  18. pydac3-3.0.0/docs/guide/08_extending.md +231 -0
  19. pydac3-3.0.0/docs/manual/00_framework_map.md +372 -0
  20. pydac3-3.0.0/docs/manual/01_inputs.md +943 -0
  21. pydac3-3.0.0/docs/manual/02_pydac_core.md +637 -0
  22. pydac3-3.0.0/docs/manual/03_pymrm_discretization.md +316 -0
  23. pydac3-3.0.0/docs/manual/04_governing_equations.md +387 -0
  24. pydac3-3.0.0/docs/manual/05_cycle_steps.md +558 -0
  25. pydac3-3.0.0/docs/manual/06_post_processing.md +2100 -0
  26. pydac3-3.0.0/docs/manual/07_nsga2_optimization.md +202 -0
  27. pydac3-3.0.0/examples/README.md +117 -0
  28. pydac3-3.0.0/examples/cases/01_first_steps.json +16 -0
  29. pydac3-3.0.0/examples/cases/02_custom_case.json +86 -0
  30. pydac3-3.0.0/examples/cases/03_css_tvsa.json +16 -0
  31. pydac3-3.0.0/examples/cases/04_1d_vs_2d.json +18 -0
  32. pydac3-3.0.0/examples/cases/05_nsga2_bounds.json +8 -0
  33. pydac3-3.0.0/examples/cases/05_nsga2_trial.json +15 -0
  34. pydac3-3.0.0/examples/cases/06_breakthrough_validation.json +120 -0
  35. pydac3-3.0.0/examples/cases/07_apdes_nfc_sorbent.json +34 -0
  36. pydac3-3.0.0/examples/cases/07_new_isotherm.json +18 -0
  37. pydac3-3.0.0/examples/cases/quick_1D.json +33 -0
  38. pydac3-3.0.0/examples/data/zanco2022_13x/README.md +51 -0
  39. pydac3-3.0.0/examples/data/zanco2022_13x/center.csv +902 -0
  40. pydac3-3.0.0/examples/data/zanco2022_13x/co2.csv +595 -0
  41. pydac3-3.0.0/examples/data/zanco2022_13x/half_radius.csv +902 -0
  42. pydac3-3.0.0/examples/data/zanco2022_13x/wall.csv +902 -0
  43. pydac3-3.0.0/examples/notebooks/01_first_steps.ipynb +895 -0
  44. pydac3-3.0.0/examples/notebooks/02_custom_case.ipynb +3347 -0
  45. pydac3-3.0.0/examples/notebooks/03_css_tvsa.ipynb +6480 -0
  46. pydac3-3.0.0/examples/notebooks/04_1d_vs_2d.ipynb +959 -0
  47. pydac3-3.0.0/examples/notebooks/05_nsga2_trial.ipynb +1890 -0
  48. pydac3-3.0.0/examples/notebooks/06_breakthrough_validation.ipynb +673 -0
  49. pydac3-3.0.0/examples/notebooks/07_new_isotherm.ipynb +860 -0
  50. pydac3-3.0.0/pyproject.toml +109 -0
  51. pydac3-3.0.0/runners/__init__.py +1 -0
  52. pydac3-3.0.0/runners/run_NSGA2.py +34 -0
  53. pydac3-3.0.0/runners/run_css_simulation.py +86 -0
  54. pydac3-3.0.0/runners/run_steps_simulation.py +85 -0
  55. pydac3-3.0.0/runners/validate_config.py +16 -0
  56. pydac3-3.0.0/src/pydac/__init__.py +59 -0
  57. pydac3-3.0.0/src/pydac/api.py +1022 -0
  58. pydac3-3.0.0/src/pydac/cli.py +596 -0
  59. pydac3-3.0.0/src/pydac/config/__init__.py +116 -0
  60. pydac3-3.0.0/src/pydac/config/bed_profiles.py +32 -0
  61. pydac3-3.0.0/src/pydac/config/cli.py +138 -0
  62. pydac3-3.0.0/src/pydac/config/contract.py +147 -0
  63. pydac3-3.0.0/src/pydac/config/cycle.py +255 -0
  64. pydac3-3.0.0/src/pydac/config/derivations.py +138 -0
  65. pydac3-3.0.0/src/pydac/config/errors.py +36 -0
  66. pydac3-3.0.0/src/pydac/config/execution.py +19 -0
  67. pydac3-3.0.0/src/pydac/config/input_help.py +138 -0
  68. pydac3-3.0.0/src/pydac/config/json_schema/experiment.schema.json +1019 -0
  69. pydac3-3.0.0/src/pydac/config/launch.py +37 -0
  70. pydac3-3.0.0/src/pydac/config/loader.py +593 -0
  71. pydac3-3.0.0/src/pydac/config/migrations.py +554 -0
  72. pydac3-3.0.0/src/pydac/config/model_validation.py +200 -0
  73. pydac3-3.0.0/src/pydac/config/nulls.py +103 -0
  74. pydac3-3.0.0/src/pydac/config/operating.py +127 -0
  75. pydac3-3.0.0/src/pydac/config/profile.py +78 -0
  76. pydac3-3.0.0/src/pydac/config/schema.py +448 -0
  77. pydac3-3.0.0/src/pydac/config/schema_generation.py +173 -0
  78. pydac3-3.0.0/src/pydac/config/sections.py +178 -0
  79. pydac3-3.0.0/src/pydac/config/serialization.py +58 -0
  80. pydac3-3.0.0/src/pydac/config/settings.py +156 -0
  81. pydac3-3.0.0/src/pydac/config/steps.py +265 -0
  82. pydac3-3.0.0/src/pydac/config/terminal.py +216 -0
  83. pydac3-3.0.0/src/pydac/config/validation.py +113 -0
  84. pydac3-3.0.0/src/pydac/core/TVSA_cycle.py +558 -0
  85. pydac3-3.0.0/src/pydac/core/__init__.py +1 -0
  86. pydac3-3.0.0/src/pydac/core/bed_architectures/__init__.py +197 -0
  87. pydac3-3.0.0/src/pydac/core/bed_architectures/base.py +886 -0
  88. pydac3-3.0.0/src/pydac/core/bed_architectures/channeling.py +683 -0
  89. pydac3-3.0.0/src/pydac/core/bed_architectures/packed_bed.py +879 -0
  90. pydac3-3.0.0/src/pydac/core/column_model.py +2976 -0
  91. pydac3-3.0.0/src/pydac/core/column_model_factory.py +118 -0
  92. pydac3-3.0.0/src/pydac/core/column_model_input.py +82 -0
  93. pydac3-3.0.0/src/pydac/core/isotherm_models.py +942 -0
  94. pydac3-3.0.0/src/pydac/core/kinetic_models.py +155 -0
  95. pydac3-3.0.0/src/pydac/core/outlet_reporting.py +58 -0
  96. pydac3-3.0.0/src/pydac/core/pymrm_caching.py +487 -0
  97. pydac3-3.0.0/src/pydac/core/solver.py +742 -0
  98. pydac3-3.0.0/src/pydac/core/sparsity_patterns/__init__.py +1 -0
  99. pydac3-3.0.0/src/pydac/core/sparsity_patterns/analytical_sparsity.py +293 -0
  100. pydac3-3.0.0/src/pydac/core/sparsity_patterns/numerical_sparsity.py +132 -0
  101. pydac3-3.0.0/src/pydac/core/species_catalog.py +206 -0
  102. pydac3-3.0.0/src/pydac/core/state_layout.py +530 -0
  103. pydac3-3.0.0/src/pydac/core/ternary_thermodynamics_separators.py +140 -0
  104. pydac3-3.0.0/src/pydac/core/thermodynamics_separators.py +120 -0
  105. pydac3-3.0.0/src/pydac/extensions.py +60 -0
  106. pydac3-3.0.0/src/pydac/inputs/__init__.py +1 -0
  107. pydac3-3.0.0/src/pydac/inputs/case_io.py +378 -0
  108. pydac3-3.0.0/src/pydac/inputs/case_terminal.py +91 -0
  109. pydac3-3.0.0/src/pydac/inputs/defaults/__init__.py +28 -0
  110. pydac3-3.0.0/src/pydac/inputs/defaults/_rules.py +97 -0
  111. pydac3-3.0.0/src/pydac/inputs/defaults/adsorption.py +87 -0
  112. pydac3-3.0.0/src/pydac/inputs/defaults/column.py +138 -0
  113. pydac3-3.0.0/src/pydac/inputs/defaults/execution.py +162 -0
  114. pydac3-3.0.0/src/pydac/inputs/defaults/mixture.py +54 -0
  115. pydac3-3.0.0/src/pydac/inputs/defaults/particle.py +116 -0
  116. pydac3-3.0.0/src/pydac/inputs/defaults/profile.py +57 -0
  117. pydac3-3.0.0/src/pydac/inputs/defaults/reference.py +31 -0
  118. pydac3-3.0.0/src/pydac/inputs/defaults/solver.py +50 -0
  119. pydac3-3.0.0/src/pydac/inputs/defaults/steps.py +684 -0
  120. pydac3-3.0.0/src/pydac/post_processing/__init__.py +1 -0
  121. pydac3-3.0.0/src/pydac/post_processing/context/__init__.py +1 -0
  122. pydac3-3.0.0/src/pydac/post_processing/context/runtime_store.py +56 -0
  123. pydac3-3.0.0/src/pydac/post_processing/context/simulation_context.py +192 -0
  124. pydac3-3.0.0/src/pydac/post_processing/context/store.py +67 -0
  125. pydac3-3.0.0/src/pydac/post_processing/kpi/__init__.py +1 -0
  126. pydac3-3.0.0/src/pydac/post_processing/kpi/cycle_kpis.py +1229 -0
  127. pydac3-3.0.0/src/pydac/post_processing/kpi/plotting.py +1160 -0
  128. pydac3-3.0.0/src/pydac/post_processing/kpi/reporting.py +962 -0
  129. pydac3-3.0.0/src/pydac/post_processing/metrics/__init__.py +1 -0
  130. pydac3-3.0.0/src/pydac/post_processing/metrics/cycle_data.py +24 -0
  131. pydac3-3.0.0/src/pydac/post_processing/metrics/cycle_data_loader.py +265 -0
  132. pydac3-3.0.0/src/pydac/post_processing/metrics/cycle_metrics.py +303 -0
  133. pydac3-3.0.0/src/pydac/post_processing/metrics/step_metrics.py +304 -0
  134. pydac3-3.0.0/src/pydac/post_processing/metrics/step_metrics_store.py +121 -0
  135. pydac3-3.0.0/src/pydac/post_processing/optimization/__init__.py +1 -0
  136. pydac3-3.0.0/src/pydac/post_processing/optimization/nsga2_post_processing.py +607 -0
  137. pydac3-3.0.0/src/pydac/post_processing/profiles/__init__.py +1 -0
  138. pydac3-3.0.0/src/pydac/post_processing/profiles/cyclic_plotting.py +929 -0
  139. pydac3-3.0.0/src/pydac/post_processing/profiles/step_plotting.py +1757 -0
  140. pydac3-3.0.0/src/pydac/post_processing/profiles/step_post_processing.py +1722 -0
  141. pydac3-3.0.0/src/pydac/starter_kit.py +115 -0
  142. pydac3-3.0.0/src/pydac/utils/__init__.py +12 -0
  143. pydac3-3.0.0/src/pydac/utils/aspect_ratios.py +56 -0
  144. pydac3-3.0.0/src/pydac/utils/campaign.py +21 -0
  145. pydac3-3.0.0/src/pydac/utils/column/__init__.py +40 -0
  146. pydac3-3.0.0/src/pydac/utils/column/runtime_properties.py +147 -0
  147. pydac3-3.0.0/src/pydac/utils/column/validation.py +313 -0
  148. pydac3-3.0.0/src/pydac/utils/css/__init__.py +43 -0
  149. pydac3-3.0.0/src/pydac/utils/css/cycle.py +533 -0
  150. pydac3-3.0.0/src/pydac/utils/css/plotting.py +71 -0
  151. pydac3-3.0.0/src/pydac/utils/css/profiles.py +140 -0
  152. pydac3-3.0.0/src/pydac/utils/css/pruning.py +26 -0
  153. pydac3-3.0.0/src/pydac/utils/css/runner.py +273 -0
  154. pydac3-3.0.0/src/pydac/utils/flow_transforms.py +188 -0
  155. pydac3-3.0.0/src/pydac/utils/logger.py +76 -0
  156. pydac3-3.0.0/src/pydac/utils/model_registry.py +395 -0
  157. pydac3-3.0.0/src/pydac/utils/nsga2/__init__.py +13 -0
  158. pydac3-3.0.0/src/pydac/utils/nsga2/artifacts.py +73 -0
  159. pydac3-3.0.0/src/pydac/utils/nsga2/checkpoint.py +621 -0
  160. pydac3-3.0.0/src/pydac/utils/nsga2/decisions.py +121 -0
  161. pydac3-3.0.0/src/pydac/utils/nsga2/evaluation.py +234 -0
  162. pydac3-3.0.0/src/pydac/utils/nsga2/logging.py +660 -0
  163. pydac3-3.0.0/src/pydac/utils/nsga2/warm_start.py +316 -0
  164. pydac3-3.0.0/src/pydac/utils/plot_helpers.py +126 -0
  165. pydac3-3.0.0/src/pydac/utils/postprocessing/__init__.py +1 -0
  166. pydac3-3.0.0/src/pydac/utils/postprocessing/context_model.py +215 -0
  167. pydac3-3.0.0/src/pydac/utils/postprocessing/context_schema.py +452 -0
  168. pydac3-3.0.0/src/pydac/utils/postprocessing/cyclic_profiles.py +204 -0
  169. pydac3-3.0.0/src/pydac/utils/postprocessing/normalization.py +138 -0
  170. pydac3-3.0.0/src/pydac/utils/postprocessing/outlet.py +47 -0
  171. pydac3-3.0.0/src/pydac/utils/postprocessing/runtime_report.py +696 -0
  172. pydac3-3.0.0/src/pydac/utils/postprocessing/saved_solution.py +171 -0
  173. pydac3-3.0.0/src/pydac/utils/postprocessing/terminal_state.py +230 -0
  174. pydac3-3.0.0/src/pydac/utils/provenance.py +345 -0
  175. pydac3-3.0.0/src/pydac/utils/run/__init__.py +35 -0
  176. pydac3-3.0.0/src/pydac/utils/run/config.py +167 -0
  177. pydac3-3.0.0/src/pydac/utils/run/resume.py +272 -0
  178. pydac3-3.0.0/src/pydac/utils/run/steps.py +124 -0
  179. pydac3-3.0.0/src/pydac/utils/run/validation.py +263 -0
  180. pydac3-3.0.0/src/pydac/utils/solver/__init__.py +155 -0
  181. pydac3-3.0.0/src/pydac/utils/solver/composition_domain.py +138 -0
  182. pydac3-3.0.0/src/pydac/utils/solver/event_config.py +101 -0
  183. pydac3-3.0.0/src/pydac/utils/solver/events.py +390 -0
  184. pydac3-3.0.0/src/pydac/utils/solver/flags.py +26 -0
  185. pydac3-3.0.0/src/pydac/utils/solver/jacobian.py +28 -0
  186. pydac3-3.0.0/src/pydac/utils/solver/outcome.py +149 -0
  187. pydac3-3.0.0/src/pydac/utils/solver/oxygen_hot_bed_audit.py +511 -0
  188. pydac3-3.0.0/src/pydac/utils/solver/persistence.py +31 -0
  189. pydac3-3.0.0/src/pydac/utils/solver/pressure_plateau.py +128 -0
  190. pydac3-3.0.0/src/pydac/utils/solver/reporting.py +83 -0
  191. pydac3-3.0.0/src/pydac/utils/solver/sparsity.py +211 -0
  192. pydac3-3.0.0/src/pydac/utils/solver/species_balance.py +197 -0
  193. pydac3-3.0.0/src/pydac/utils/tvsa/__init__.py +77 -0
  194. pydac3-3.0.0/src/pydac/utils/tvsa/cycle_steps.py +58 -0
  195. pydac3-3.0.0/src/pydac/utils/tvsa/paths.py +87 -0
  196. pydac3-3.0.0/src/pydac/utils/tvsa/reporting.py +114 -0
  197. pydac3-3.0.0/src/pydac/utils/tvsa/steps.py +163 -0
  198. pydac3-3.0.0/src/pydac/utils/tvsa/termination.py +186 -0
  199. pydac3-3.0.0/src/pydac/utils/vector_drag.py +48 -0
  200. pydac3-3.0.0/src/pydac/utils/version.py +7 -0
  201. pydac3-3.0.0/src/pydac/workflows/__init__.py +1 -0
  202. pydac3-3.0.0/src/pydac/workflows/orchestrator_NSGA2.py +1532 -0
  203. pydac3-3.0.0/src/pydac/workflows/orchestrator_TVSA_cycle_css.py +409 -0
  204. pydac3-3.0.0/src/pydac/workflows/orchestrator_TVSA_steps.py +119 -0
  205. pydac3-3.0.0/tests/__init__.py +1 -0
  206. pydac3-3.0.0/tests/baselines/comparison_rules.json +40 -0
  207. pydac3-3.0.0/tests/baselines/hardcoding_inventory.json +324 -0
  208. pydac3-3.0.0/tests/baselines/v3_smoke_startup.json +270 -0
  209. pydac3-3.0.0/tests/cases/v3_smoke_startup.json +595 -0
  210. pydac3-3.0.0/tests/conftest.py +7 -0
  211. pydac3-3.0.0/tests/neutral_packed_bed.py +26 -0
  212. pydac3-3.0.0/tests/test_adsorption_registries.py +311 -0
  213. pydac3-3.0.0/tests/test_column_validation_utils.py +430 -0
  214. pydac3-3.0.0/tests/test_composition_domain_guard.py +181 -0
  215. pydac3-3.0.0/tests/test_energy_accumulation_source.py +174 -0
  216. pydac3-3.0.0/tests/test_energy_ledger_gate.py +358 -0
  217. pydac3-3.0.0/tests/test_export_settings.py +260 -0
  218. pydac3-3.0.0/tests/test_extensions.py +118 -0
  219. pydac3-3.0.0/tests/test_generic_configuration.py +397 -0
  220. pydac3-3.0.0/tests/test_initial_solid_loadings.py +255 -0
  221. pydac3-3.0.0/tests/test_inlet_flux_profile.py +126 -0
  222. pydac3-3.0.0/tests/test_moo_candidate_artifacts.py +253 -0
  223. pydac3-3.0.0/tests/test_moo_compact_persistence.py +292 -0
  224. pydac3-3.0.0/tests/test_moo_cooling_target_variable.py +130 -0
  225. pydac3-3.0.0/tests/test_moo_solver_failure_gate.py +407 -0
  226. pydac3-3.0.0/tests/test_moo_strong_resume.py +514 -0
  227. pydac3-3.0.0/tests/test_nsga2_campaigns.py +341 -0
  228. pydac3-3.0.0/tests/test_outlet_product_line.py +583 -0
  229. pydac3-3.0.0/tests/test_packed_bed_surface.py +86 -0
  230. pydac3-3.0.0/tests/test_phase0_baselines.py +159 -0
  231. pydac3-3.0.0/tests/test_phase5a_initialization.py +225 -0
  232. pydac3-3.0.0/tests/test_phase5b_rhs_solver_sparsity.py +327 -0
  233. pydac3-3.0.0/tests/test_phase6_postprocessing_runtime.py +492 -0
  234. pydac3-3.0.0/tests/test_phase6b_tier0_rhs.py +173 -0
  235. pydac3-3.0.0/tests/test_phase7_extension_example.py +105 -0
  236. pydac3-3.0.0/tests/test_profile_inventory_outlet.py +397 -0
  237. pydac3-3.0.0/tests/test_public_provenance.py +289 -0
  238. pydac3-3.0.0/tests/test_pydac_api_cli.py +940 -0
  239. pydac3-3.0.0/tests/test_release_reconciliation.py +105 -0
  240. pydac3-3.0.0/tests/test_runner_resume.py +284 -0
  241. pydac3-3.0.0/tests/test_sorbent_declarations.py +338 -0
  242. pydac3-3.0.0/tests/test_species_catalog.py +121 -0
  243. pydac3-3.0.0/tests/test_species_dispersion_correction.py +233 -0
  244. pydac3-3.0.0/tests/test_stable_drag_inversion.py +77 -0
  245. pydac3-3.0.0/tests/test_starter_kit.py +110 -0
  246. pydac3-3.0.0/tests/test_state_layout.py +249 -0
  247. pydac3-3.0.0/tests/test_termination_validation.py +127 -0
  248. pydac3-3.0.0/tests/test_vector_drag.py +91 -0
  249. pydac3-3.0.0/tests/test_wall_channeling_reduced.py +1183 -0
  250. pydac3-3.0.0/tests/tools/__init__.py +1 -0
  251. pydac3-3.0.0/tests/tools/generate_v3_smoke_baseline.py +203 -0
@@ -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.