reaktoro-pse 0.3.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 (79) hide show
  1. reaktoro_pse-0.3.0/.github/workflows/checks.yml +123 -0
  2. reaktoro_pse-0.3.0/.gitignore +165 -0
  3. reaktoro_pse-0.3.0/COPYRIGHT.md +19 -0
  4. reaktoro_pse-0.3.0/LICENSE.md +49 -0
  5. reaktoro_pse-0.3.0/PKG-INFO +203 -0
  6. reaktoro_pse-0.3.0/README.md +191 -0
  7. reaktoro_pse-0.3.0/docs/images/reaktoro_pse.png +0 -0
  8. reaktoro_pse-0.3.0/docs/images/reaktoro_pse.svg +597 -0
  9. reaktoro_pse-0.3.0/pyproject.toml +25 -0
  10. reaktoro_pse-0.3.0/requirements-dev.txt +5 -0
  11. reaktoro_pse-0.3.0/setup.cfg +4 -0
  12. reaktoro_pse-0.3.0/src/reaktoro_pse/__init__.py +4 -0
  13. reaktoro_pse-0.3.0/src/reaktoro_pse/core/__init__.py +0 -0
  14. reaktoro_pse-0.3.0/src/reaktoro_pse/core/pyomo_property_writer/__init__.py +0 -0
  15. reaktoro_pse-0.3.0/src/reaktoro_pse/core/pyomo_property_writer/property_functions.py +121 -0
  16. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_block_builder.py +522 -0
  17. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_coupled_solver.py +302 -0
  18. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_gray_box.py +166 -0
  19. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_inputs.py +655 -0
  20. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_jacobian.py +459 -0
  21. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_outputs.py +1021 -0
  22. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_solver.py +310 -0
  23. reaktoro_pse-0.3.0/src/reaktoro_pse/core/reaktoro_state.py +825 -0
  24. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/__init__.py +0 -0
  25. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/test_reaktoro_builder.py +292 -0
  26. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/test_reaktoro_inputs.py +414 -0
  27. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/test_reaktoro_jacobian.py +491 -0
  28. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/test_reaktoro_outputs.py +187 -0
  29. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/test_reaktoro_solver.py +566 -0
  30. reaktoro_pse-0.3.0/src/reaktoro_pse/core/tests/test_reaktoro_state.py +356 -0
  31. reaktoro_pse-0.3.0/src/reaktoro_pse/core/util_classes/__init__.py +0 -0
  32. reaktoro_pse-0.3.0/src/reaktoro_pse/core/util_classes/cyipopt_solver.py +79 -0
  33. reaktoro_pse-0.3.0/src/reaktoro_pse/core/util_classes/hessian_functions.py +579 -0
  34. reaktoro_pse-0.3.0/src/reaktoro_pse/core/util_classes/rkt_inputs.py +387 -0
  35. reaktoro_pse-0.3.0/src/reaktoro_pse/core/util_classes/tests/__init__.py +0 -0
  36. reaktoro_pse-0.3.0/src/reaktoro_pse/core/util_classes/tests/test_rkt_inputs.py +46 -0
  37. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/biogas_combustion.py +214 -0
  38. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/__init__.py +0 -0
  39. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/acid_base_addition_comparison.py +84 -0
  40. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/comparison_utils.py +178 -0
  41. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/phreeqc_data.json +652 -0
  42. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/phreeqc_data_waterq4f.json +641 -0
  43. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/precipitation_comparison.py +121 -0
  44. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/solution_mixing_comparison.py +241 -0
  45. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/standard_model.py +141 -0
  46. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/tests/test_comparsion_exmaples.py +142 -0
  47. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/vapor_pressure_comparison.py +103 -0
  48. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/water_removal_comparison.py +71 -0
  49. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/redox_tracking.py +243 -0
  50. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/simple_desalination.py +216 -0
  51. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/simple_ion_exchange.py +312 -0
  52. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/tests/test_examples.py +150 -0
  53. reaktoro_pse-0.3.0/src/reaktoro_pse/examples/thermal_precipitation.py +442 -0
  54. reaktoro_pse-0.3.0/src/reaktoro_pse/parallel_tools/parallel_manager.py +404 -0
  55. reaktoro_pse-0.3.0/src/reaktoro_pse/parallel_tools/reaktoro_block_manager.py +404 -0
  56. reaktoro_pse-0.3.0/src/reaktoro_pse/parallel_tools/tests/test_manager.py +198 -0
  57. reaktoro_pse-0.3.0/src/reaktoro_pse/reaktoro_block.py +1136 -0
  58. reaktoro_pse-0.3.0/src/reaktoro_pse/reaktoro_block_config/hessian_options.py +111 -0
  59. reaktoro_pse-0.3.0/src/reaktoro_pse/reaktoro_block_config/input_options.py +310 -0
  60. reaktoro_pse-0.3.0/src/reaktoro_pse/reaktoro_block_config/jacobian_options.py +144 -0
  61. reaktoro_pse-0.3.0/src/reaktoro_pse/reaktoro_block_config/reaktoro_solver_options.py +116 -0
  62. reaktoro_pse-0.3.0/src/reaktoro_pse/tests/__init__.py +0 -0
  63. reaktoro_pse-0.3.0/src/reaktoro_pse/tests/test_reaktoro_block.py +700 -0
  64. reaktoro_pse-0.3.0/src/reaktoro_pse/tests/test_solvers.py +23 -0
  65. reaktoro_pse-0.3.0/src/reaktoro_pse/tests/test_version.py +17 -0
  66. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/basic_reaktoro_block_interaction.ipynb +1610 -0
  67. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/direct_prop.png +0 -0
  68. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/integration_with_nf.ipynb +1489 -0
  69. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/integration_with_ro.ipynb +1570 -0
  70. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/reaktoro_pse_api.png +0 -0
  71. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/softening_acid_ro.png +0 -0
  72. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/softening_acid_ro_example.ipynb +1317 -0
  73. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/solute_parameters.json +45 -0
  74. reaktoro_pse-0.3.0/src/reaktoro_pse/tutorials/spec_block.png +0 -0
  75. reaktoro_pse-0.3.0/src/reaktoro_pse.egg-info/PKG-INFO +203 -0
  76. reaktoro_pse-0.3.0/src/reaktoro_pse.egg-info/SOURCES.txt +77 -0
  77. reaktoro_pse-0.3.0/src/reaktoro_pse.egg-info/dependency_links.txt +1 -0
  78. reaktoro_pse-0.3.0/src/reaktoro_pse.egg-info/requires.txt +6 -0
  79. reaktoro_pse-0.3.0/src/reaktoro_pse.egg-info/top_level.txt +1 -0
@@ -0,0 +1,123 @@
1
+ name: Checks
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ tags: ['*']
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.head_ref }}
11
+ cancel-in-progress: true
12
+
13
+ env:
14
+ PYTEST_ADDOPTS: --color=yes
15
+ PIP_PROGRESS_BAR: "off"
16
+ KERNEL_NAME: reaktoro-pse-dev
17
+ defaults:
18
+ run:
19
+ # -l: login shell, needed when using Conda:
20
+ shell: bash -l {0}
21
+
22
+ jobs:
23
+ code-formatting:
24
+ name: Check code is formatted (Black)
25
+ # OS and/or Python version don't make a difference, so we choose ubuntu and 3.12 as defaults
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: actions/setup-python@v5
30
+ with:
31
+ python-version: '3.12'
32
+ - name: Install Black
33
+ # unlike the other jobs, we don't need to install all the dev dependencies,
34
+ # but we still want to specify the Black version to use in requirements-dev.txt for local development
35
+ # so we extract the relevant line and pass it to a simple `pip install`
36
+ run: |
37
+ black_requirement="$(grep '^black==' requirements-dev.txt)"
38
+ pip install "$black_requirement"
39
+ - name: Run Black to verify that the committed code is formatted
40
+ run: |
41
+ black --check .
42
+
43
+ pytest:
44
+ name: pytest (${{ matrix.os }}/${{ matrix.python-version }}/${{ matrix.install-mode }})
45
+ runs-on: ${{ matrix.os-version }}
46
+ needs: [code-formatting]
47
+ strategy:
48
+ fail-fast: false
49
+ matrix:
50
+ install-mode:
51
+ - dev
52
+ - standard
53
+ python-version:
54
+ - "3.10"
55
+ - "3.11"
56
+ - "3.12"
57
+ - "3.13"
58
+ os:
59
+ - linux
60
+ - win64
61
+ # - macos # need ma27
62
+ include:
63
+ - os: linux
64
+ os-version: ubuntu-22.04
65
+ - os: win64
66
+ os-version: windows-2022
67
+ # - os: macos
68
+ # os-version: macos-15
69
+ - install-mode: dev
70
+ python-version: "3.11" # choice of Python version is arbitrary among those in matrix
71
+ coverage: "true"
72
+ steps:
73
+ - if: matrix.install-mode == 'dev' || matrix.install-mode == 'yaml'
74
+ uses: actions/checkout@v4
75
+ - uses: conda-incubator/setup-miniconda@v3
76
+ with:
77
+ python-version: ${{ matrix.python-version }}
78
+ miniforge-version: latest
79
+ channels: conda-forge
80
+ activate-environment: ${{ matrix.install-mode == 'dev' || matrix.install-mode == 'yaml' && 'reaktoro-pse-dev' || 'reaktoro-pse' }}
81
+ - if: matrix.install-mode == 'dev'
82
+ name: Install (dev)
83
+ run: |
84
+ conda install cyipopt reaktoro
85
+ pip install -r requirements-dev.txt
86
+ - if: matrix.install-mode == 'standard'
87
+ name: Install (standard)
88
+ run: |
89
+ conda install cyipopt reaktoro
90
+ pip install "git+${{ format('{0}/{1}@{2}', github.server_url, github.repository, github.ref) }}"
91
+ - name: Install (idaes-solvers)
92
+ run: |
93
+ idaes get-extensions
94
+ - if: matrix.coverage
95
+ name: Enable coverage for pytest
96
+ run: echo PYTEST_ADDOPTS="$PYTEST_ADDOPTS --cov --cov-report=xml" >> $GITHUB_ENV
97
+ - name: Run pytest
98
+ run: |
99
+ pip install pytest # ensure pytest is installed (should do nothing if already present from requirements-dev.txt)
100
+ pytest --pyargs reaktoro_pse --verbose
101
+ - if: matrix.install-mode == 'dev'
102
+ name: Install Jupyter kernel
103
+ run: |
104
+ jupyter kernelspec list
105
+ python -m ipykernel install --user --name "${{ env.KERNEL_NAME }}"
106
+ jupyter kernelspec list
107
+
108
+ - if: matrix.install-mode == 'dev'
109
+ name: Run pytest with nbmake
110
+ run: |
111
+ # watertap is needed to run the following notebooks in src/reaktoro_pse/tutorials:
112
+ # - basic_reaktoro_block_interaction.ipynb
113
+ # - integration_with_ro.ipynb
114
+ pip install watertap
115
+ pip install "idaes-pse>=2.8.0"
116
+ pytest --nbmake --nbmake-kernel="${{ env.KERNEL_NAME }}" src/reaktoro_pse/tutorials/*.ipynb
117
+ - name: Upload coverage report as job artifact
118
+ if: matrix.coverage
119
+ uses: actions/upload-artifact@v4
120
+ with:
121
+ name: coverage-report-${{ matrix.os }}
122
+ path: coverage.xml
123
+ if-no-files-found: error
@@ -0,0 +1,165 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
110
+ .pdm.toml
111
+ .pdm-python
112
+ .pdm-build/
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ env/
128
+ venv/
129
+ ENV/
130
+ env.bak/
131
+ venv.bak/
132
+
133
+ # Spyder project settings
134
+ .spyderproject
135
+ .spyproject
136
+
137
+ # Rope project settings
138
+ .ropeproject
139
+
140
+ # mkdocs documentation
141
+ /site
142
+
143
+ # mypy
144
+ .mypy_cache/
145
+ .dmypy.json
146
+ dmypy.json
147
+
148
+ # Pyre type checker
149
+ .pyre/
150
+
151
+ # pytype static type analyzer
152
+ .pytype/
153
+
154
+ # Cython debug symbols
155
+ cython_debug/
156
+
157
+ # PyCharm
158
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
161
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
+ #.idea/
163
+ *.jpg
164
+ /.vscode
165
+ src/reaktoro_pse/copyright.txt
@@ -0,0 +1,19 @@
1
+ Copyright
2
+ =========
3
+
4
+ WaterTAP Copyright (c) 2020-2026, The Regents of the University of California,
5
+ through Lawrence Berkeley National Laboratory, Oak Ridge National
6
+ Laboratory, National Laboratory of the Rockies, and National Energy
7
+ Technology Laboratory (subject to receipt of any required approvals from
8
+ the U.S. Dept. of Energy). All rights reserved.
9
+
10
+ If you have questions about your rights to use or distribute this software,
11
+ please contact Berkeley Lab's Intellectual Property Office at
12
+ IPO@lbl.gov.
13
+
14
+ NOTICE. This Software was developed under funding from the U.S. Department
15
+ of Energy and the U.S. Government consequently retains certain rights. As
16
+ such, the U.S. Government has been granted for itself and others acting on
17
+ its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
18
+ Software to reproduce, distribute copies to the public, prepare derivative
19
+ works, and perform publicly and display publicly, and to permit others to do so.
@@ -0,0 +1,49 @@
1
+ License Agreement
2
+ =================
3
+
4
+ WaterTAP Copyright (c) 2020-2026, The Regents of the University of California,
5
+ through Lawrence Berkeley National Laboratory, Oak Ridge National Laboratory,
6
+ National Laboratory of the Rockies, and National Energy Technology
7
+ Laboratory (subject to receipt of any required approvals from the U.S. Dept.
8
+ of Energy). All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions are met:
12
+
13
+ 1. Redistributions of source code must retain the above copyright notice,
14
+ this list of conditions and the following disclaimer.
15
+
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in the
18
+ documentation and/or other materials provided with the distribution.
19
+
20
+ 3. Neither the name of the University of California, Lawrence Berkeley
21
+ National Laboratory, Oak Ridge National Laboratory, National Renewable
22
+ Energy Laboratory, National Energy Technology Laboratory, U.S. Dept.
23
+ of Energy nor the names of its contributors may be used to endorse or
24
+ promote products derived from this software without specific prior written
25
+ permission.
26
+
27
+
28
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
+ POSSIBILITY OF SUCH DAMAGE.
39
+
40
+ You are under no obligation whatsoever to provide any bug fixes, patches,
41
+ or upgrades to the features, functionality or performance of the source
42
+ code ("Enhancements") to anyone; however, if you choose to make your
43
+ Enhancements available either publicly, or directly to Lawrence Berkeley
44
+ National Laboratory, without imposing a separate written license agreement
45
+ for such Enhancements, then you hereby grant the following license: a
46
+ non-exclusive, royalty-free perpetual license to install, use, modify,
47
+ prepare derivative works, incorporate into other computer software,
48
+ distribute, and sublicense such enhancements or derivative works thereof,
49
+ in binary and source code form.
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: reaktoro-pse
3
+ Version: 0.3.0
4
+ Description-Content-Type: text/markdown
5
+ License-File: LICENSE.md
6
+ Requires-Dist: pyomo
7
+ Requires-Dist: watertap-solvers>=24.12.9
8
+ Provides-Extra: testing
9
+ Requires-Dist: pytest>=8; extra == "testing"
10
+ Requires-Dist: nbmake; extra == "testing"
11
+ Dynamic: license-file
12
+
13
+
14
+ <img src="docs\images\reaktoro_pse.png" width="400"/>
15
+
16
+ ## 1. Overview
17
+ This is a package for configuring [Reaktoro](https://reaktoro.org/index.html) as a gray box model in [Pyomo](https://pyomo.readthedocs.io/en/stable/), [IDAES-PSE](https://idaes-pse.readthedocs.io/en/stable/), and [WaterTAP](https://watertap.readthedocs.io/en/stable/) modeling libraries. This package is not meant to replace or act as a higher level API for Reaktoro - it is only meant to enable setting up Reaktoro equilibrium problems as blocks on Pyomo models and automate transferring Reaktoro data into Pyomo variables.
18
+
19
+ ## 2. Prerequisites
20
+ **The user must familiarize thyself with Reaktoro options and usage, especially when selecting Reaktoro provided databases, database files, and activity models for aqueous, solid, and gas phases. This package does not automatically select any of these options, and will use ideal models by default.**
21
+
22
+ * Please refer here for information on [Reaktoro supported databases](https://reaktoro.org/tutorials/basics/loading-databases.html) (all are supported)
23
+ * Please refer here for information on [Reaktoro supported activity models](https://reaktoro.org/tutorials/basics/specifying-activity-models.html) (all are supported, included chain operations, or passing in pre-configured activity models)
24
+
25
+ **By default the package will use:**
26
+
27
+ * **Database:** [PhreeqcDatabase](https://reaktoro.org/api/classReaktoro_1_1PhreeqcDatabase.html)
28
+ * **Data file:** [pitzer.dat](https://reaktoro.org/api/classReaktoro_1_1PhreeqcDatabase.html)
29
+ * **Aqueous activity models:** [ActivityModelIdealAqueous](https://reaktoro.org/api/namespaceReaktoro.html#ae431d4c8a1f283910ae1cf35024091b8)
30
+ * **Gas activity models:** [ActivityModelIdealGas](https://reaktoro.org/api/namespaceReaktoro.html#a7a0788a5a863d987a88b81303d80b427)
31
+ * **Solid activity models:** [ActivityModelIdealSolution](https://reaktoro.org/api/namespaceReaktoro.html#a6581d5c0cde36cae6d9c46dbc32d56f8)
32
+ * **Ion exchange activity modells:** [ActivityModelIonExchange](https://reaktoro.org/api/namespaceReaktoro.html#a6581d5c0cde36cae6d9c46dbc32d56f8)
33
+
34
+ ## 3. Inputs and outputs of the Reaktoro blocks
35
+ The Reaktoro blocks built by this package are designed to solve an equilibrium problem using user provided apparent species or true species, temperature, pressure, and pH, which are broken down to base elements and equilibrated within Reaktoro to provide exact speciation and equilibrium state. Using this state the block can return various information supported by Reaktoro:
36
+
37
+ * Converted Property Types - used by default as they provide exact derivatives for common properties:
38
+ * vaporPressure - vapor pressure for specie in Pa
39
+ * osmoticPressure - osmotic pressure for specie in Pa
40
+ * elementAmount - amount of element in system in mol
41
+ * charge - solution charge balance
42
+ * alkalinityAsCaCO3 - solution alkalinity as CaCO3
43
+ * scalingTendencySaturationIndex - Saturation index of a phase
44
+ * scalingTendency - scaling tendencies of a phase (10^saturation index)
45
+ * pH - solution pH
46
+
47
+ If a property is not available in converted property types, reaktoro-pse can access any property from reaktoro which wil use numerical derivatives when exact derivatives are not available:
48
+ * [Chemical properties](https://reaktoro.org/api/classReaktoro_1_1ChemicalProps.html)
49
+ * [Aqueous properties](https://reaktoro.org/api/classReaktoro_1_1AqueousProps.html)
50
+ * Pyomo build properties, which are custom properties built in Pyomo that use chemical properties or aqueous properties as inputs
51
+
52
+ Note: Only Reaktoro properties that return a single floating point or real value are supported, as they will be directly matched to a [Pyomo Var](https://pyomo.readthedocs.io/en/stable/pyomo_modeling_components/Variables.html). Reaktoro functions that return arrays or strings are not supported.
53
+
54
+ ## 4. Tutorials, Examples, and Comparisons
55
+ Currently, repo includes several tutorials and examples.
56
+
57
+ *Tutorials:*
58
+
59
+ 1. [Demonstration of working with Reaktoro block that shows](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/tutorials/basic_reaktoro_block_interaction.ipynb)
60
+ * How to balance feed charge with ReaktoroBlock
61
+ * Provide exact speciation
62
+ * Build reaktoro block with speciation_block option
63
+
64
+ 2. [Demonstration add ReaktoroBlock to 1D Reverse Osmosis model](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/tutorials/integration_with_ro.ipynb)
65
+ * How to add indexed ReaktoroBlocks [WaterTAP RO1D model](https://watertap.readthedocs.io/en/stable/technical_reference/unit_models/reverse_osmosis_1D.html) for calculation of osmotic pressure and scaling tendencies
66
+
67
+ 3. [Demonstration add ReaktoroBlock to Nano filtration model](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/tutorials/integration_with_nf.ipynb)
68
+ * How to add indexed ReaktoroBlocks to WaterTAP NF ZO model for calculation of osmotic pressure and scaling tendencies
69
+
70
+ 4. [Treatment train with Softening -> acid -> desalination process modeling with Reaktoro-PSE](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/tutorials/softening_acid_ro_example.ipynb)
71
+ * How to model softening
72
+ * How to model acid addition
73
+ * How to model scaling tendencies
74
+ * How to optimize softening and acid addition to control scaling and minimize chemical dosing costs.
75
+
76
+ *Examples:*
77
+
78
+ 1. [Example of adding ReaktoroBlock to basic desalination problem](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/simple_desalination.py) that demonstrates how to:
79
+ * Setup up basic ReaktoroBlock
80
+ * Calculate basic properties for Scaling Tendency, pH, and Osmotic pressure
81
+ * Optimize system pH for operation at target Scaling Tendency
82
+ 2. [Example of thermal precipitation](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/thermal_precipitation.py) that demonstrates how to:
83
+ * Configure different database from default
84
+ * Get enthalpy and vapor pressure from Reaktoro
85
+ * Setup precipitation calculation
86
+ * Setup simulation for removal of Calcite over different temperatures and estimate required energy input
87
+ 3. [Example of ion exchange calculations](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/simple_ion_exchange.py) that demonstrates how to:
88
+ * Set up ReaktoroBlock for charge neutralizing the feed composition
89
+ * Use outputs from speciation block as inputs into a second property block
90
+ * Add Ion Exchange phase and species into ReaktoroBlock
91
+ * Optimize addition of acid and bases for maximizing Calcium removal selectivity over Magnesium
92
+ 4. [Example of biogas combustion](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/biogas_combustion.py) that demonstrates how to:
93
+ * Set up ReaktoroBlock for customized database
94
+ * Use Condensed phase
95
+
96
+ *Comparisons of Reaktoro-pse to PhreeqC when simulating*
97
+
98
+ These comparisons further demonstrate how to setup Reaktoro-pse for each type of calculation.
99
+
100
+ 1. [Water removal from solution (e.g evaporative processes)](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/water_removal_comparison.py)
101
+ 2. [Vapor pressure calculation at different temperatures](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/vapor_pressure_comparison.py)
102
+ 3. [Precipitation of mineral phases](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/precipitation_comparison.py)
103
+ 4. [Mixing of two solution](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/examples/reaktoro_pse_to_phreeqc_comparison/solution_mixing_comparison.py)
104
+
105
+ ## 5. Solvers
106
+ To-date, this has only been tested with [cyipopt](https://cyipopt.readthedocs.io/en/stable/) - other solvers have not been tested.
107
+ * For accessing other [HSL linear solvers](http://www.hsl.rl.ac.uk/ipopt/) beyond MUMPS (such as MA27, MA57, etc. solver common to WaterTAP and IDAES-PSE) follow [these instructions](https://cyipopt.readthedocs.io/en/latest/install.html) for adding it to cyipopt.
108
+
109
+ ## 6. Known issues
110
+
111
+ ### Closing dual infeasibility
112
+ In some cases Ipopt might struggle to close unscaled dual infeasibility even when primal is reduced to <1e-8. This will be typically seen in the solver trace, that shows **inf_pr** being reduced to <1e-8 and **inf_du** stops being reduced and solver does not terminate or terminates with **Solved to Acceptable level**. [This is a result of using approximated hessian in the GrayBox model causing issues in calculations of dual infeasibility error.](https://list.coin-or.org/pipermail/ipopt/2007-February/000700.html)
113
+
114
+ #### Solutions
115
+ A. Set Ipopt solver option "recalc_y" to "yes"
116
+
117
+ This option will force Ipopt to use least squares method to calculate dual infeasibility, potentially improving accuracy of its estimates and reduce it to below tolerance level. Details on the [recalc_y](https://coin-or.github.io/Ipopt/OPTIONS.html#OPT_recalc_y) and [recalc_y_feas_tol](https://coin-or.github.io/Ipopt/OPTIONS.html#OPT_recalc_y_feas_tol).
118
+
119
+ cy_solver = get_solver(solver="cyipopt-watertap")
120
+ cy_solver.options['recalc_y']='yes'
121
+ cy_solver.options["recalc_y_feas_tol"] = 1e-2
122
+
123
+
124
+ B. Use exact derivatives instead of numeric
125
+
126
+ The numeric derivatives carry additional errors that reduce accuracy in estimates of dual infeasibility. You can check which outputs in your Reaktoro block are exact, calculated, or numeric by using **your_reaktoro_block.display_jacobian_outputs()**.
127
+
128
+ If option "A" did not work, using exact derivatives can potentially solve this issue. This can be accomplished by using properties with exact derivatives listed in [JacobianRows class](https://github.com/watertap-org/reaktoro-pse/blob/main/src/reaktoro_pse/core/reaktoro_jacobian.py). These properties can be used to write Pyomo constraints that calculate the desired property. These derivatvies can be used in two ways:
129
+ - through use of ConvertedPropTypes, here we apply chain rule to calculate exact derivatives for desired function
130
+ - through use of PyomoProperties, where we pass outputs with exact derivatives to a Pyomo constraint.
131
+
132
+ Examples and available properties can be found in */src/reaktoro_pse/core/reaktoro_outputs.py*
133
+
134
+ ### Failing due to iterates diverging
135
+ In some cases you might experience a failed solve with error
136
+
137
+ EXIT: Iterates diverging; problem might be unbounded.
138
+
139
+ This, in general, is a result of bad scaling. If your model solves with out a ReaktoroBlock, then the likely culprit is autoscaling for Jacobian (and possibly variables as well). In this case its recommend to provide manual scaling for the jacobian via user scaling option when building Reaktoro, for example as follows (check thermal_precipitation.py example):
140
+
141
+ jacobian_options={
142
+ "user_scaling": {
143
+ ("molarEnthalpy", None): 1,
144
+ ("specificHeatCapacityConstP", None): 1,
145
+ },
146
+ }
147
+
148
+ You can check the jacobian scaling by calling:
149
+
150
+ your_reaktoro_block.display_jacobian_scaling()
151
+
152
+ An alternative is to increase the divergence tolerance:
153
+
154
+ solver.options["diverging_iterates_tol"] = 1e30
155
+
156
+ ## 7. Requesting new features or issues
157
+ Please include a minimal example using Reaktoro for your specific feature or issue request if possible. Please also include full traceback for errors the occur.
158
+
159
+ ## 8. Compatibility
160
+ Reaktoro-pse depends on the following packages and/or versions:
161
+
162
+ - Python 3.9 through 3.12
163
+ - Reaktoro>=2.12.3
164
+ - CyIpopt 1.4.1
165
+ - Pyomo>=6.8.0
166
+ - idaes-pse>=2.5.0
167
+
168
+
169
+ ## 9. Getting started
170
+
171
+ ### Prerequisites
172
+
173
+ - A conda or miniforge distribution compatible with `conda-forge`, e.g. [Miniforge](https://github.com/conda-forge/miniforge?tab=readme-ov-file#download)
174
+ - Git (needed by [setuptools_scm](https://setuptools-scm.readthedocs.io/en/latest/) to set the version dynamically during installation of the Python package distribution)
175
+
176
+ ### Installation (Conda)
177
+ ```sh
178
+ conda activate $YOUR_ENV
179
+ conda install cyipopt reaktoro
180
+ pip install git+https://github.com/watertap-org/reaktoro-pse.git
181
+ ```
182
+
183
+ ## For Contributors
184
+ ### Installation
185
+ ```sh
186
+ git clone https://github.com/watertap-org/reaktoro-pse.git
187
+ conda create --name reaktoro-pse-dev --yes python=3.12
188
+ conda activate reaktoro-pse-dev
189
+ conda install cyipopt reaktoro
190
+ install -e.
191
+ ```
192
+ ### Running tests
193
+
194
+ ```sh
195
+ conda activate reaktoro-pse-dev
196
+ pytest --pyargs reaktoro_pse --verbose
197
+ ```
198
+
199
+ ### Before committing
200
+
201
+ ```sh
202
+ black .
203
+ ```