pymrm 2.2.0__tar.gz → 2.2.2__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 (89) hide show
  1. {pymrm-2.2.0 → pymrm-2.2.2}/.github/workflows/analysis.yml +4 -33
  2. pymrm-2.2.2/.github/workflows/build.yml +38 -0
  3. {pymrm-2.2.0 → pymrm-2.2.2}/.github/workflows/test.yml +2 -0
  4. {pymrm-2.2.0 → pymrm-2.2.2}/.github/workflows/verification.yml +4 -0
  5. {pymrm-2.2.0 → pymrm-2.2.2}/CITATION.cff +2 -2
  6. {pymrm-2.2.0 → pymrm-2.2.2}/PKG-INFO +1 -1
  7. {pymrm-2.2.0 → pymrm-2.2.2}/docs/installation.md +2 -2
  8. {pymrm-2.2.0 → pymrm-2.2.2}/docs/sphinx/modules.rst +1 -1
  9. {pymrm-2.2.0 → pymrm-2.2.2}/docs/sphinx/pymrm.rst +19 -8
  10. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/build_documentation.sh +10 -0
  11. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/__init__.py +9 -45
  12. pymrm-2.2.2/src/pymrm/_version.py +24 -0
  13. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/convect.py +81 -159
  14. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/coupling.py +63 -135
  15. pymrm-2.2.2/src/pymrm/grid.py +87 -0
  16. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/interpolate.py +130 -120
  17. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/numjac.py +64 -75
  18. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/operators.py +92 -75
  19. pymrm-2.2.2/src/pymrm/solve.py +146 -0
  20. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm.egg-info/PKG-INFO +1 -1
  21. {pymrm-2.2.0 → pymrm-2.2.2}/tutorials/introduction_and_start.ipynb +1 -1
  22. pymrm-2.2.0/.github/workflows/build.yml +0 -23
  23. pymrm-2.2.0/src/pymrm/_version.py +0 -34
  24. pymrm-2.2.0/src/pymrm/grid.py +0 -82
  25. pymrm-2.2.0/src/pymrm/solve.py +0 -159
  26. {pymrm-2.2.0 → pymrm-2.2.2}/.coveragerc +0 -0
  27. {pymrm-2.2.0 → pymrm-2.2.2}/.flake8 +0 -0
  28. {pymrm-2.2.0 → pymrm-2.2.2}/.github/black-formatting.yml +0 -0
  29. {pymrm-2.2.0 → pymrm-2.2.2}/.github/workflows/python-publish.yml +0 -0
  30. {pymrm-2.2.0 → pymrm-2.2.2}/.github/workflows/update-citation-cff.yml +0 -0
  31. {pymrm-2.2.0 → pymrm-2.2.2}/.github/workflows/validate-citation-cff.yml +0 -0
  32. {pymrm-2.2.0 → pymrm-2.2.2}/.gitignore +0 -0
  33. {pymrm-2.2.0 → pymrm-2.2.2}/.gitlab-ci.yml +0 -0
  34. {pymrm-2.2.0 → pymrm-2.2.2}/.vscode/launch_debugpy.json +0 -0
  35. {pymrm-2.2.0 → pymrm-2.2.2}/.vscode/settings_pytest.json +0 -0
  36. {pymrm-2.2.0 → pymrm-2.2.2}/Dockerfile +0 -0
  37. {pymrm-2.2.0 → pymrm-2.2.2}/LICENSE +0 -0
  38. {pymrm-2.2.0 → pymrm-2.2.2}/MANIFEST.in +0 -0
  39. {pymrm-2.2.0 → pymrm-2.2.2}/README.md +0 -0
  40. {pymrm-2.2.0 → pymrm-2.2.2}/docs/compile_sphinx.md +0 -0
  41. {pymrm-2.2.0 → pymrm-2.2.2}/docs/dependencies_format.md +0 -0
  42. {pymrm-2.2.0 → pymrm-2.2.2}/docs/helpers.md +0 -0
  43. {pymrm-2.2.0 → pymrm-2.2.2}/docs/sphinx/Makefile +0 -0
  44. {pymrm-2.2.0 → pymrm-2.2.2}/docs/sphinx/conf.py +0 -0
  45. {pymrm-2.2.0 → pymrm-2.2.2}/docs/sphinx/index.rst +0 -0
  46. {pymrm-2.2.0 → pymrm-2.2.2}/docs/sphinx/make.bat +0 -0
  47. {pymrm-2.2.0 → pymrm-2.2.2}/environment.yml +0 -0
  48. {pymrm-2.2.0 → pymrm-2.2.2}/examples/counter_current_reaction.ipynb +0 -0
  49. {pymrm-2.2.0 → pymrm-2.2.2}/examples/counter_diffusion_reaction.ipynb +0 -0
  50. {pymrm-2.2.0 → pymrm-2.2.2}/examples/darcy_flow.ipynb +0 -0
  51. {pymrm-2.2.0 → pymrm-2.2.2}/examples/lid_driven_cavity.ipynb +0 -0
  52. {pymrm-2.2.0 → pymrm-2.2.2}/examples/membrane_module_2D.ipynb +0 -0
  53. {pymrm-2.2.0 → pymrm-2.2.2}/examples/membrane_module_2D_Sievert.ipynb +0 -0
  54. {pymrm-2.2.0 → pymrm-2.2.2}/examples/optimization_example.ipynb +0 -0
  55. {pymrm-2.2.0 → pymrm-2.2.2}/examples/particle_model_effectiveness.ipynb +0 -0
  56. {pymrm-2.2.0 → pymrm-2.2.2}/examples/surface_reaction.ipynb +0 -0
  57. {pymrm-2.2.0 → pymrm-2.2.2}/examples/tvd.ipynb +0 -0
  58. {pymrm-2.2.0 → pymrm-2.2.2}/examples/unsteady_convection_reaction.ipynb +0 -0
  59. {pymrm-2.2.0 → pymrm-2.2.2}/examples/unsteady_diffusion_reaction_2D.ipynb +0 -0
  60. {pymrm-2.2.0 → pymrm-2.2.2}/pyproject.toml +0 -0
  61. {pymrm-2.2.0 → pymrm-2.2.2}/requirements.txt +0 -0
  62. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/run_examples.py +0 -0
  63. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/run_exercises.py +0 -0
  64. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/run_linter.sh +0 -0
  65. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/run_notebook.py +0 -0
  66. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/run_tutorials.py +0 -0
  67. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/run_unit_tests.sh +0 -0
  68. {pymrm-2.2.0 → pymrm-2.2.2}/scripts/split_notebook.py +0 -0
  69. {pymrm-2.2.0 → pymrm-2.2.2}/setup.cfg +0 -0
  70. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm/helpers.py +0 -0
  71. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm.egg-info/SOURCES.txt +0 -0
  72. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm.egg-info/dependency_links.txt +0 -0
  73. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm.egg-info/requires.txt +0 -0
  74. {pymrm-2.2.0 → pymrm-2.2.2}/src/pymrm.egg-info/top_level.txt +0 -0
  75. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_convect.py +0 -0
  76. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_coupling.py +0 -0
  77. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_csr_format.py +0 -0
  78. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_grid.py +0 -0
  79. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_helpers.py +0 -0
  80. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_integration.py +0 -0
  81. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_interpolate.py +0 -0
  82. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_numjac.py +0 -0
  83. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_operators.py +0 -0
  84. {pymrm-2.2.0 → pymrm-2.2.2}/test/test_solve.py +0 -0
  85. {pymrm-2.2.0 → pymrm-2.2.2}/tutorials/diffusion_2D.ipynb +0 -0
  86. {pymrm-2.2.0 → pymrm-2.2.2}/tutorials/diffusion_first_order_kinetics.ipynb +0 -0
  87. {pymrm-2.2.0 → pymrm-2.2.2}/tutorials/diffusion_model_class.ipynb +0 -0
  88. {pymrm-2.2.0 → pymrm-2.2.2}/tutorials/nonlinear_kinetics.ipynb +0 -0
  89. {pymrm-2.2.0 → pymrm-2.2.2}/tutorials/stationary_diffusion.ipynb +0 -0
@@ -21,6 +21,8 @@ jobs:
21
21
 
22
22
  steps:
23
23
  - uses: actions/checkout@v4
24
+ - name: Configure git safe.directory for container
25
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
24
26
 
25
27
  - name: test flake 8
26
28
  run: scripts/run_linter.sh
@@ -42,6 +44,8 @@ jobs:
42
44
 
43
45
  steps:
44
46
  - uses: actions/checkout@v4
47
+ - name: Configure git safe.directory for container
48
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
45
49
  - name: Install myst-parser
46
50
  run: pip install myst-parser
47
51
  - name: Ensure _static directory exists
@@ -64,36 +68,3 @@ jobs:
64
68
  with:
65
69
  name: Documentation
66
70
  path: docs/sphinx/_build/html*
67
-
68
- publish-analysis:
69
- # For details checkout https://github.com/marketplace/actions/publish-test-results
70
- runs-on: ubuntu-latest
71
- container:
72
- image: davevader/pymrm_linux:1.0
73
- # workaround, potentially leave the user as root in dockerfile
74
- # see here: https://github.com/actions/checkout/issues/956
75
- options: --user root
76
-
77
- name: Publish Tests Results
78
- needs: [linter]
79
- permissions:
80
- checks: write
81
- # only needed unless run with comment_mode: off
82
- pull-requests: write
83
- # only needed for private repository
84
- contents: read
85
- # only needed for private repository
86
- issues: read
87
- if: always()
88
-
89
- steps:
90
- - name: Download Artifacts
91
- uses: actions/download-artifact@v4
92
- with:
93
- path: artifacts
94
-
95
- - name: Publish Analysis
96
- uses: EnricoMi/publish-unit-test-result-action@v2
97
- with:
98
- files: |
99
- artifacts/linter/*.xml
@@ -0,0 +1,38 @@
1
+ name: Build
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - dev
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ - dev
12
+
13
+ jobs:
14
+ install:
15
+ runs-on: ubuntu-latest
16
+ container:
17
+ image: python:3.10
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - name: Configure git safe.directory for container
22
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
23
+
24
+ - name: Test Install
25
+ run: python -m pip install .
26
+
27
+ documentation:
28
+ runs-on: ubuntu-latest
29
+ container:
30
+ image: python:3.10
31
+
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - name: Configure git safe.directory for container
35
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
36
+
37
+ - name: Build documentation (with apidoc regeneration)
38
+ run: scripts/build_documentation.sh
@@ -24,6 +24,8 @@ jobs:
24
24
 
25
25
  steps:
26
26
  - uses: actions/checkout@v4
27
+ - name: Configure git safe.directory for container
28
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
27
29
 
28
30
  - name: Install dependencies
29
31
  run: pip install pytest
@@ -21,6 +21,8 @@ jobs:
21
21
 
22
22
  steps:
23
23
  - uses: actions/checkout@v4
24
+ - name: Configure git safe.directory for container
25
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
24
26
 
25
27
  - name: run tutorials
26
28
  run: |
@@ -37,6 +39,8 @@ jobs:
37
39
 
38
40
  steps:
39
41
  - uses: actions/checkout@v4
42
+ - name: Configure git safe.directory for container
43
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
40
44
  - name: Run examples
41
45
  run: |
42
46
  python -m pip install .
@@ -1,6 +1,6 @@
1
1
  cff-version: 1.2.0
2
2
  title: "pymrm: Python package for Multiphase Reactor Modeling"
3
- version: "2.2.0"
3
+ version: "2.2.1"
4
4
  message: "If you use pymrm in your work, please cite the version you used."
5
5
  authors:
6
6
  - family-names: Peters
@@ -9,7 +9,7 @@ authors:
9
9
  - family-names: van Sint Annaland
10
10
  given-names: M.
11
11
  orcid: "https://orcid.org/0000-0002-2903-7443"
12
- date-released: "2026-01-09"
12
+ date-released: "2026-04-17"
13
13
  identifiers:
14
14
  - type: doi
15
15
  value: 10.5281/zenodo.17065798
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymrm
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: Functions for multiphase reactor modeling
5
5
  Author-email: "E.A.J.F. Peters" <e.a.j.f.peters@tue.nl>, "M. van Sint Annaland" <M.v.SintAnnaland@tue.nl>, "M. Galanti" <m.galanti@tue.nl>, "D.R. Rieder" <d.r.rieder@tue.nl>
6
6
  Maintainer-email: "E.A.J.F. Peters" <e.a.j.f.peters@tue.nl>
@@ -82,7 +82,7 @@ PyMRM is available on PyPI and includes all necessary dependencies.
82
82
  ## Verifying the Installation
83
83
 
84
84
  1. **Test the Installation**:
85
- - Navigate to the `examples` folder in the PyMRM repository or download example notebooks from the [PyMRM documentation](https://multiscale-modelling-multiphase-flows.github.io/pymrm-book).
85
+ - Navigate to the `examples` folder in the PyMRM repository or download example notebooks from the [PyMRM documentation](https://computational-chemical-engineering.github.io/pymrm-book).
86
86
  - Open a notebook in VS Code or Jupyter Notebook and execute the cells to verify that PyMRM and its dependencies are working correctly.
87
87
 
88
88
  2. **Optional: Test in Spyder**:
@@ -94,4 +94,4 @@ PyMRM is available on PyPI and includes all necessary dependencies.
94
94
 
95
95
  ## Conclusion
96
96
 
97
- You have successfully set up your environment for using PyMRM. Whether you use VS Code or Spyder, you are now ready to start modeling multiphase reactors. For further guidance, refer to the [PyMRM documentation](https://multiscale-modelling-multiphase-flows.github.io/pymrm-book).
97
+ You have successfully set up your environment for using PyMRM. Whether you use VS Code or Spyder, you are now ready to start modeling multiphase reactors. For further guidance, refer to the [PyMRM documentation](https://computational-chemical-engineering.github.io/pymrm-book).
@@ -1,4 +1,4 @@
1
- pyMRM
1
+ pymrm
2
2
  =====
3
3
 
4
4
  .. toctree::
@@ -1,66 +1,77 @@
1
+ pymrm package
2
+ =============
3
+
1
4
  Submodules
2
- ==========
5
+ ----------
3
6
 
4
7
  pymrm.convect module
5
8
  --------------------
6
9
 
7
10
  .. automodule:: pymrm.convect
8
11
  :members:
12
+ :show-inheritance:
9
13
  :undoc-members:
14
+
15
+ pymrm.coupling module
16
+ ---------------------
17
+
18
+ .. automodule:: pymrm.coupling
19
+ :members:
10
20
  :show-inheritance:
21
+ :undoc-members:
11
22
 
12
23
  pymrm.grid module
13
24
  -----------------
14
25
 
15
26
  .. automodule:: pymrm.grid
16
27
  :members:
17
- :undoc-members:
18
28
  :show-inheritance:
29
+ :undoc-members:
19
30
 
20
31
  pymrm.helpers module
21
32
  --------------------
22
33
 
23
34
  .. automodule:: pymrm.helpers
24
35
  :members:
25
- :undoc-members:
26
36
  :show-inheritance:
37
+ :undoc-members:
27
38
 
28
39
  pymrm.interpolate module
29
40
  ------------------------
30
41
 
31
42
  .. automodule:: pymrm.interpolate
32
43
  :members:
33
- :undoc-members:
34
44
  :show-inheritance:
45
+ :undoc-members:
35
46
 
36
47
  pymrm.numjac module
37
48
  -------------------
38
49
 
39
50
  .. automodule:: pymrm.numjac
40
51
  :members:
41
- :undoc-members:
42
52
  :show-inheritance:
53
+ :undoc-members:
43
54
 
44
55
  pymrm.operators module
45
56
  ----------------------
46
57
 
47
58
  .. automodule:: pymrm.operators
48
59
  :members:
49
- :undoc-members:
50
60
  :show-inheritance:
61
+ :undoc-members:
51
62
 
52
63
  pymrm.solve module
53
64
  ------------------
54
65
 
55
66
  .. automodule:: pymrm.solve
56
67
  :members:
57
- :undoc-members:
58
68
  :show-inheritance:
69
+ :undoc-members:
59
70
 
60
71
  Module contents
61
72
  ---------------
62
73
 
63
74
  .. automodule:: pymrm
64
75
  :members:
65
- :undoc-members:
66
76
  :show-inheritance:
77
+ :undoc-members:
@@ -5,6 +5,16 @@
5
5
 
6
6
  pip install myst-parser # workaround. Should be included in Docker image?
7
7
  pip install -e .
8
+ sphinx-apidoc -f -o docs/sphinx src/pymrm
9
+ if [[ "${CI}" == "true" ]]; then
10
+ api_rst_files=(docs/sphinx/pymrm.rst docs/sphinx/modules.rst)
11
+ if ! git diff --quiet HEAD -- "${api_rst_files[@]}"; then
12
+ echo "Detected outdated autogenerated Sphinx API files:"
13
+ git --no-pager diff HEAD -- "${api_rst_files[@]}"
14
+ echo "Run 'sphinx-apidoc -f -o docs/sphinx src/pymrm' and commit the updated rst files."
15
+ exit 1
16
+ fi
17
+ fi
8
18
  cd docs/sphinx
9
19
  mkdir -p _static
10
20
  make html 2>documentation_errors.txt
@@ -1,50 +1,14 @@
1
- """
2
- pymrm: A Python Package for Multiphase Reactor Modeling
3
-
4
- This package provides a comprehensive set of tools for modeling multiphase reactors,
5
- including grid generation, numerical operators, convection schemes, interpolation methods,
6
- nonlinear solvers, and utility functions.
7
-
8
- Submodules:
9
- - grid: Functions for generating uniform and non-uniform grids.
10
- - operator: Construction of gradient and divergence operators for finite volume methods.
11
- - convection: High-resolution convection schemes and TVD limiters.
12
- - interpolate: Interpolation techniques between staggered and cell-centered grids.
13
- - solve: Nonlinear solvers and numerical approaches.
14
- - helpers: Utility functions supporting core operations.
15
- - numjac: Numerical Jacobian construction for nonlinear systems.
16
-
17
- Example Usage:
18
- .. code-block:: python
19
-
20
- import numpy as np
21
- import matplotlib.pyplot as plt
22
- from pymrm import construct_grad, construct_div
23
-
24
- # Define the grid
25
- shape = (100,)
26
- x_f = np.linspace(0, 1, shape[0]+1)
27
- x_c = 0.5*(x_f[1:] + x_f[:-1])
28
-
29
- # Set boundary conditions
30
- bc_L = {a: 0, b:1, d:1}
31
- bc_R = {a: 0, b:1, d:0}
32
- grad_mat, grad_bc = construct_grad(shape, x_f, x_c, bc=(bc_L, bc_R))
33
- div_mat = construct_div(shape, x_f)
34
- lapl_mat = div_mat @ grad_mat
35
- lapl_bc = div_mat @ grad_bc
36
-
37
- c = np.zeros(shape)
38
- c[:] = lapl_mat.solve(lapl_bc)
39
- plt.plot(x_c, c)
1
+ """Top-level package for :mod:`pymrm`.
40
2
 
41
- Authors:
42
- - E.A.J.F. Peters
43
- - M. van Sint Annaland
44
- - M. Galanti
45
- - D.R. Rieder
3
+ The package provides numerical building blocks for multiphase reactor models,
4
+ including:
46
5
 
47
- License: MIT License
6
+ * grid generation utilities;
7
+ * sparse gradient, divergence, and convective-flux operators;
8
+ * interpolation routines between cell-centered and staggered layouts;
9
+ * numerical Jacobian approximation tools;
10
+ * nonlinear solver helpers for implicit schemes; and
11
+ * coupling helpers for multi-domain/interface formulations.
48
12
  """
49
13
 
50
14
  from .grid import generate_grid, non_uniform_grid
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '2.2.2'
22
+ __version_tuple__ = version_tuple = (2, 2, 2)
23
+
24
+ __commit_id__ = commit_id = 'g471977efe'
@@ -1,28 +1,4 @@
1
- """
2
- convection.py
3
-
4
- This submodule of pymrm provides functions to construct convective flux matrices using
5
- upwind schemes and apply Total Variation Diminishing (TVD) limiters for numerical stability.
6
-
7
- Functions:
8
- - construct_convflux_upwind: Constructs the convective flux matrix using the upwind scheme.
9
- - construct_convflux_upwind_int: Constructs the internal convective flux matrix.
10
- - construct_convflux_bc: Constructs the convective flux matrix for boundary conditions.
11
- - upwind: Upwind TVD limiter.
12
- - minmod: Minmod TVD limiter.
13
- - osher: Osher TVD limiter.
14
- - clam: CLAM TVD limiter.
15
- - muscl: MUSCL TVD limiter.
16
- - smart: SMART TVD limiter.
17
- - stoic: STOIC TVD limiter.
18
- - vanleer: Van Leer TVD limiter.
19
-
20
- Dependencies:
21
- - numpy
22
- - scipy.sparse (for csc_array)
23
- - pymrm.grid (for optional grid generation)
24
- - pymrm.helpers (for boundary condition handling)
25
- """
1
+ """Convective-flux operators and TVD limiter functions."""
26
2
 
27
3
  import math
28
4
  import numpy as np
@@ -36,23 +12,33 @@ def construct_convflux_upwind(
36
12
  shape, x_f, x_c=None, bc=(None, None), v=1.0, axis=0, shapes_d=(None, None),
37
13
  format="csc"
38
14
  ):
39
- """
40
- Constructs the convective flux matrix using the upwind scheme.
41
-
42
- Args:
43
- shape (tuple or int): Shape of the multi-dimensional array. If an integer is provided, it is treated as 1D.
44
- x_f (ndarray): Face positions.
45
- x_c (ndarray, optional): Cell positions. If not provided, it will be calculated based on the face array.
46
- bc (tuple, optional): Boundary conditions as a tuple of dictionaries
47
- for left and right boundaries. Default is (None, None).
48
- v (float or ndarray): Velocities on face positions. Can be a scalar or an array.
49
- axis (int, optional): The axis along which the convection takes place. Default is 0.
50
- shapes_d (tuple, optional): Shapes for boundary condition matrices. Default is (None, None).
51
- format (str, optional): Sparse format, ``'csc'`` (default) or ``'csr'``.
52
-
53
- Returns:
54
- csc_array or csr_array: Convective flux matrix for internal faces.
55
- csc_array or csr_array: Convective flux matrix for boundary conditions.
15
+ """Construct a first-order upwind convective-flux operator.
16
+
17
+ Parameters
18
+ ----------
19
+ shape : tuple[int, ...] or int
20
+ Cell-centered field shape.
21
+ x_f : array_like
22
+ Face coordinates along ``axis``.
23
+ x_c : array_like, optional
24
+ Cell-center coordinates. If omitted, arithmetic midpoints are used.
25
+ bc : tuple[dict | None, dict | None], optional
26
+ Left and right boundary-condition dictionaries with keys ``a``, ``b``,
27
+ and ``d``.
28
+ v : float or array_like, optional
29
+ Face velocity field. Scalars and broadcastable arrays are accepted.
30
+ axis : int, optional
31
+ Convection axis.
32
+ shapes_d : tuple[tuple | None, tuple | None], optional
33
+ Optional source-vector shapes for boundary inhomogeneities.
34
+ format : {'csc', 'csr'}, optional
35
+ Sparse format for returned operator matrices.
36
+
37
+ Returns
38
+ -------
39
+ tuple
40
+ Without ``shapes_d``: ``(conv_matrix, conv_bc)``.
41
+ With ``shapes_d``: ``(conv_matrix, conv_bc_left, conv_bc_right)``.
56
42
  """
57
43
  if isinstance(shape, int):
58
44
  shape = (shape,)
@@ -84,17 +70,23 @@ def construct_convflux_upwind(
84
70
 
85
71
 
86
72
  def construct_convflux_upwind_int(shape, v=1.0, axis=0, format="csc"):
87
- """
88
- Constructs the convective flux matrix for internal faces using the upwind scheme.
89
-
90
- Args:
91
- shape (tuple): Shape of the multi-dimensional array.
92
- v (float or ndarray): Velocity array. Can be a scalar or an array.
93
- axis (int, optional): The axis along which the numerical differentiation is performed. Default is 0.
94
- format (str, optional): Sparse format, ``'csc'`` (default) or ``'csr'``.
95
-
96
- Returns:
97
- csc_array or csr_array: Convective flux matrix for internal faces.
73
+ """Construct the internal-face upwind advection operator.
74
+
75
+ Parameters
76
+ ----------
77
+ shape : tuple[int, ...]
78
+ Cell-centered field shape.
79
+ v : float or array_like, optional
80
+ Face velocity field.
81
+ axis : int, optional
82
+ Convection axis.
83
+ format : {'csc', 'csr'}, optional
84
+ Sparse format of the returned matrix.
85
+
86
+ Returns
87
+ -------
88
+ scipy.sparse.csc_array or scipy.sparse.csr_array
89
+ Sparse matrix mapping cell-centered values to interior face fluxes.
98
90
  """
99
91
  shape_f = shape[:axis] + (shape[axis] + 1,) + shape[axis + 1:]
100
92
  shape_t = (math.prod(shape[:axis]), shape[axis], math.prod(shape[axis + 1:]))
@@ -141,24 +133,34 @@ def construct_convflux_bc(
141
133
  shape, x_f, x_c=None, bc=(None, None), v=1.0, axis=0, shapes_d=(None, None),
142
134
  format="csc"
143
135
  ):
144
- """
145
- Constructs the convective flux matrix for boundary faces using the upwind scheme.
146
-
147
- Args:
148
- shape (tuple): Shape of the multi-dimensional array.
149
- x_f (ndarray): Face positions.
150
- x_c (ndarray, optional): Cell-centered positions. If not provided,
151
- it is calculated based on the face array.
152
- bc (tuple, optional): Boundary conditions as a tuple of dictionaries
153
- for left and right boundaries. Default is (None, None).
154
- v (float or ndarray): Velocity array. Can be a scalar or an array.
155
- axis (int, optional): The axis along which the numerical differentiation is performed. Default is 0.
156
- shapes_d (tuple, optional): Shapes for boundary condition matrices. Default is (None, None).
157
- format (str, optional): Sparse format, ``'csc'`` (default) or ``'csr'``.
158
-
159
- Returns:
160
- csc_array or csr_array: Convective flux matrix for internal faces.
161
- csc_array or csr_array: Convective flux matrix for boundary conditions.
136
+ """Construct boundary-face upwind corrections and source terms.
137
+
138
+ Parameters
139
+ ----------
140
+ shape : tuple[int, ...]
141
+ Cell-centered field shape.
142
+ x_f : array_like
143
+ Face coordinates along ``axis``.
144
+ x_c : array_like, optional
145
+ Cell-center coordinates.
146
+ bc : tuple[dict | None, dict | None], optional
147
+ Left and right boundary-condition dictionaries with keys ``a``, ``b``,
148
+ and ``d``.
149
+ v : float or array_like, optional
150
+ Face velocity field.
151
+ axis : int, optional
152
+ Convection axis.
153
+ shapes_d : tuple[tuple | None, tuple | None], optional
154
+ Optional source-vector shapes for inhomogeneous boundary terms.
155
+ format : {'csc', 'csr'}, optional
156
+ Sparse format for returned operator matrices.
157
+
158
+ Returns
159
+ -------
160
+ tuple
161
+ ``(conv_matrix_bc, conv_bc)`` when ``shapes_d`` is not supplied, or
162
+ ``(conv_matrix_left, conv_bc_left, conv_matrix_right, conv_bc_right)``
163
+ otherwise.
162
164
  """
163
165
 
164
166
  # Trick: Reshape to triplet shape_t
@@ -388,33 +390,13 @@ def construct_convflux_bc(
388
390
 
389
391
 
390
392
  def upwind(normalized_c_c, normalized_x_c, normalized_x_d):
391
- """
392
- Applies the upwind TVD limiter to reduce oscillations in numerical schemes.
393
-
394
- Args:
395
- normalized_c_c (ndarray): Normalized concentration at cell centers.
396
- normalized_x_c (ndarray): Normalized position of cell centers.
397
- normalized_x_d (ndarray): Normalized position of downwind face.
398
-
399
- Returns:
400
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
401
- """
393
+ """Return zero correction (first-order upwind limiter)."""
402
394
  normalized_concentration_diff = np.zeros_like(normalized_c_c)
403
395
  return normalized_concentration_diff
404
396
 
405
397
 
406
398
  def minmod(normalized_c_c, normalized_x_c, normalized_x_d):
407
- """
408
- Applies the Minmod TVD limiter to reduce oscillations in numerical schemes.
409
-
410
- Args:
411
- normalized_c_c (ndarray): Normalized concentration at cell centers.
412
- normalized_x_c (ndarray): Normalized position of cell centers.
413
- normalized_x_d (ndarray): Normalized position of downwind face.
414
-
415
- Returns:
416
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
417
- """
399
+ """Compute the Minmod TVD correction in normalized-variable space."""
418
400
  normalized_concentration_diff = np.maximum(
419
401
  0,
420
402
  (normalized_x_d - normalized_x_c)
@@ -426,17 +408,7 @@ def minmod(normalized_c_c, normalized_x_c, normalized_x_d):
426
408
 
427
409
 
428
410
  def osher(normalized_c_c, normalized_x_c, normalized_x_d):
429
- """
430
- Applies the Osher TVD limiter to reduce oscillations in numerical schemes.
431
-
432
- Args:
433
- normalized_c_c (ndarray): Normalized concentration at cell centers.
434
- normalized_x_c (ndarray): Normalized position of cell centers.
435
- normalized_x_d (ndarray): Normalized position of downwind face.
436
-
437
- Returns:
438
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
439
- """
411
+ """Compute the Osher TVD correction in normalized-variable space."""
440
412
  normalized_concentration_diff = np.maximum(
441
413
  0,
442
414
  np.where(
@@ -449,17 +421,7 @@ def osher(normalized_c_c, normalized_x_c, normalized_x_d):
449
421
 
450
422
 
451
423
  def clam(normalized_c_c, normalized_x_c, normalized_x_d):
452
- """
453
- Applies the CLAM TVD limiter to reduce oscillations in numerical schemes.
454
-
455
- Args:
456
- normalized_c_c (ndarray): Normalized concentration at cell centers.
457
- normalized_x_c (ndarray): Normalized position of cell centers.
458
- normalized_x_d (ndarray): Normalized position of downwind face.
459
-
460
- Returns:
461
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
462
- """
424
+ """Compute the CLAM TVD correction in normalized-variable space."""
463
425
  normalized_concentration_diff = np.maximum(
464
426
  0,
465
427
  np.where(
@@ -472,17 +434,7 @@ def clam(normalized_c_c, normalized_x_c, normalized_x_d):
472
434
 
473
435
 
474
436
  def muscl(normalized_c_c, normalized_x_c, normalized_x_d):
475
- """
476
- Applies the MUSCL TVD limiter to reduce oscillations in numerical schemes.
477
-
478
- Args:
479
- normalized_c_c (ndarray): Normalized concentration at cell centers.
480
- normalized_x_c (ndarray): Normalized position of cell centers.
481
- normalized_x_d (ndarray): Normalized position of downwind face.
482
-
483
- Returns:
484
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
485
- """
437
+ """Compute the MUSCL TVD correction in normalized-variable space."""
486
438
  normalized_concentration_diff = np.maximum(
487
439
  0,
488
440
  np.where(
@@ -500,17 +452,7 @@ def muscl(normalized_c_c, normalized_x_c, normalized_x_d):
500
452
 
501
453
 
502
454
  def smart(normalized_c_c, normalized_x_c, normalized_x_d):
503
- """
504
- Applies the SMART TVD limiter to reduce oscillations in numerical schemes.
505
-
506
- Args:
507
- normalized_c_c (ndarray): Normalized concentration at cell centers.
508
- normalized_x_c (ndarray): Normalized position of cell centers.
509
- normalized_x_d (ndarray): Normalized position of downwind face.
510
-
511
- Returns:
512
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
513
- """
455
+ """Compute the SMART TVD correction in normalized-variable space."""
514
456
  normalized_concentration_diff = np.maximum(
515
457
  0,
516
458
  np.where(
@@ -544,17 +486,7 @@ def smart(normalized_c_c, normalized_x_c, normalized_x_d):
544
486
 
545
487
 
546
488
  def stoic(normalized_c_c, normalized_x_c, normalized_x_d):
547
- """
548
- Applies the STOIC TVD limiter to reduce oscillations in numerical schemes.
549
-
550
- Args:
551
- normalized_c_c (ndarray): Normalized concentration at cell centers.
552
- normalized_x_c (ndarray): Normalized position of cell centers.
553
- normalized_x_d (ndarray): Normalized position of downwind face.
554
-
555
- Returns:
556
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
557
- """
489
+ """Compute the STOIC TVD correction in normalized-variable space."""
558
490
  normalized_concentration_diff = np.maximum(
559
491
  0,
560
492
  np.where(
@@ -603,17 +535,7 @@ def stoic(normalized_c_c, normalized_x_c, normalized_x_d):
603
535
 
604
536
 
605
537
  def vanleer(normalized_c_c, normalized_x_c, normalized_x_d):
606
- """
607
- Applies the van Leer TVD limiter to reduce oscillations in numerical schemes.
608
-
609
- Args:
610
- normalized_c_c (ndarray): Normalized concentration at cell centers.
611
- normalized_x_c (ndarray): Normalized position of cell centers.
612
- normalized_x_d (ndarray): Normalized position of downwind face.
613
-
614
- Returns:
615
- ndarray: Normalized concentration difference (c_norm_d - c_norm_C).
616
- """
538
+ """Compute the van-Leer TVD correction in normalized-variable space."""
617
539
  normalized_concentration_diff = np.maximum(
618
540
  0,
619
541
  normalized_c_c