adios4dolfinx 0.7.2__tar.gz → 0.8.0.dev0__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 (41) hide show
  1. adios4dolfinx-0.8.0.dev0/PKG-INFO +145 -0
  2. adios4dolfinx-0.8.0.dev0/README.md +113 -0
  3. adios4dolfinx-0.8.0.dev0/pyproject.toml +68 -0
  4. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx/__init__.py +18 -5
  5. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx/adios2_helpers.py +290 -0
  6. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx/checkpointing.py +727 -0
  7. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx/comm_helpers.py +50 -113
  8. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx/legacy_readers.py +164 -160
  9. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx/original_checkpoint.py +369 -0
  10. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx/snapshot.py +58 -0
  11. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx/structures.py +55 -0
  12. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx/utils.py +86 -14
  13. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx/writers.py +197 -0
  14. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx.egg-info/PKG-INFO +145 -0
  15. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx.egg-info/SOURCES.txt +6 -1
  16. adios4dolfinx-0.8.0.dev0/src/adios4dolfinx.egg-info/requires.txt +20 -0
  17. adios4dolfinx-0.8.0.dev0/tests/test_attributes.py +38 -0
  18. adios4dolfinx-0.8.0.dev0/tests/test_checkpointing.py +208 -0
  19. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/tests/test_checkpointing_vector.py +85 -52
  20. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/tests/test_legacy_readers.py +25 -25
  21. adios4dolfinx-0.8.0.dev0/tests/test_mesh_writer.py +176 -0
  22. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/tests/test_meshtags.py +28 -35
  23. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/tests/test_numpy_vectorization.py +28 -25
  24. adios4dolfinx-0.8.0.dev0/tests/test_original_checkpoint.py +509 -0
  25. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/tests/test_snapshot_checkpoint.py +19 -17
  26. adios4dolfinx-0.7.2/PKG-INFO +0 -91
  27. adios4dolfinx-0.7.2/README.md +0 -60
  28. adios4dolfinx-0.7.2/pyproject.toml +0 -51
  29. adios4dolfinx-0.7.2/src/adios4dolfinx/adios2_helpers.py +0 -239
  30. adios4dolfinx-0.7.2/src/adios4dolfinx/checkpointing.py +0 -630
  31. adios4dolfinx-0.7.2/src/adios4dolfinx.egg-info/PKG-INFO +0 -91
  32. adios4dolfinx-0.7.2/src/adios4dolfinx.egg-info/requires.txt +0 -19
  33. adios4dolfinx-0.7.2/tests/test_checkpointing.py +0 -156
  34. adios4dolfinx-0.7.2/tests/test_mesh_writer.py +0 -75
  35. adios4dolfinx-0.7.2/tests/test_utils.py +0 -128
  36. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/LICENSE +0 -0
  37. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/setup.cfg +0 -0
  38. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx/py.typed +0 -0
  39. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx.egg-info/dependency_links.txt +0 -0
  40. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/src/adios4dolfinx.egg-info/top_level.txt +0 -0
  41. {adios4dolfinx-0.7.2 → adios4dolfinx-0.8.0.dev0}/tests/test_version.py +0 -0
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.1
2
+ Name: adios4dolfinx
3
+ Version: 0.8.0.dev0
4
+ Summary: Checkpointing functionality for DOLFINx meshes/functions with ADIOS2
5
+ Author-email: "Jørgen S. Dokken" <dokken@simula.no>
6
+ License: Copyright 2023 Jørgen S. Dokken
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: fenics-dolfinx>=0.8.0.dev0
17
+ Provides-Extra: test
18
+ Requires-Dist: pytest; extra == "test"
19
+ Requires-Dist: coverage; extra == "test"
20
+ Requires-Dist: ipyparallel; extra == "test"
21
+ Provides-Extra: dev
22
+ Requires-Dist: pdbpp; extra == "dev"
23
+ Requires-Dist: ipython; extra == "dev"
24
+ Requires-Dist: mypy; extra == "dev"
25
+ Requires-Dist: ruff; extra == "dev"
26
+ Provides-Extra: docs
27
+ Requires-Dist: jupyter-book; extra == "docs"
28
+ Requires-Dist: ipyparallel; extra == "docs"
29
+ Requires-Dist: ipywidgets; extra == "docs"
30
+ Provides-Extra: all
31
+ Requires-Dist: adios4dolfinx[dev,docs,test]; extra == "all"
32
+
33
+ # ADIOS2Wrappers for DOLFINx
34
+
35
+ [![MIT](https://img.shields.io/github/license/jorgensd/adios4dolfinx)](LICENSE)
36
+ [Read Latest Documentation](https://jsdokken.com/adios4dolfinx/)
37
+
38
+ This is an extension for [DOLFINx](https://github.com/FEniCS/dolfinx/) to checkpoint meshes, meshtags and functions using [ADIOS2](https://adios2.readthedocs.io/en/latest/).
39
+
40
+ The code uses the adios2 Python-wrappers to write DOLFINx objects to file, supporting N-to-M (_recoverable_) and N-to-N (_snapshot_) checkpointing.
41
+ See: [Checkpointing in DOLFINx - FEniCS 23](https://jsdokken.com/checkpointing-presentation/#/) for more information.
42
+
43
+ For scalability, the code uses [MPI Neighbourhood collectives](https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report/node200.htm) for communication across processes.
44
+
45
+ ## Installation
46
+
47
+ ### Docker
48
+
49
+ ADIOS2 is installed in the official DOLFINx containers.
50
+
51
+ ```bash
52
+ docker run -ti -v $(pwd):/root/shared -w /root/shared --name=dolfinx-checkpoint ghcr.io/fenics/dolfinx/dolfinx:nightly
53
+ ```
54
+
55
+ ### Conda
56
+
57
+ To use with conda (DOLFINx release v0.7.0 works with v0.7.3 of ADIOS4DOLFINx)
58
+
59
+ ```bash
60
+ conda create -n dolfinx-checkpoint python=3.10
61
+ conda activate dolfinx-checkpoint
62
+ conda install -c conda-forge fenics-dolfinx pip adios2
63
+ python3 -m pip install git+https://github.com/jorgensd/adios4dolfinx@v0.7.2
64
+ ```
65
+
66
+ ## Functionality
67
+
68
+ ### DOLFINx
69
+
70
+ - Reading and writing meshes, using `adios4dolfinx.read/write_mesh`
71
+ - Reading and writing meshtags associated to meshes `adios4dolfinx.read/write_meshtags`
72
+ - Reading checkpoints for any element (serial and parallel, arbitrary number of functions and timesteps per file). Use `adios4dolfinx.read/write_function`.
73
+ - Writing standalone function checkpoints relating to "original meshes", i.e. meshes read from `XDMFFile`. Use `adios4dolfinx.write_function_on_input_mesh` for this.
74
+ - Store mesh partitioning and re-read the mesh with this information, avoiding calling SCOTCH, Kahip or Parmetis.
75
+
76
+ > [!IMPORTANT]
77
+ > For checkpoints written with `write_function` to be valid, you first have to store the mesh with `write_mesh` to the checkpoint file.
78
+
79
+ > [!IMPORTANT]
80
+ > A checkpoint file supports multiple functions and multiple time steps, as long as the functions are associated with the same mesh
81
+
82
+ > [!IMPORTANT]
83
+ > Only one mesh per file is allowed
84
+
85
+ ### Backwards compatibility
86
+
87
+ > [!WARNING]
88
+ > If you are using v0.7.2, you are adviced to upgrade to v0.7.3, as it contains som crucial fixes for openmpi.
89
+
90
+ ### Legacy DOLFIN
91
+
92
+ Only checkpoints for `Lagrange` or `DG` functions are supported from legacy DOLFIN
93
+
94
+ - Reading meshes from the DOLFIN HDF5File-format
95
+ - Reading checkpoints from the DOLFIN HDF5File-format (one checkpoint per file only)
96
+ - Reading checkpoints from the DOLFIN XDMFFile-format (one checkpoint per file only, and only uses the `.h5` file)
97
+
98
+ See the [API](./docs/api) for more information.
99
+
100
+ ## Long term plan
101
+
102
+ The long term plan is to get this library merged into DOLFINx (rewritten in C++ with appropriate Python-bindings).
103
+
104
+ # Contributor guidelines
105
+ When contributing to this repository, please first [create an issue](https://github.com/jorgensd/adios4dolfinx/issues/new/choose) containing information about the missing feature or the bug that you would like to fix. Here you can discuss the change you want to make with the maintainers of the repository.
106
+
107
+ Please note we have a code of conduct, please follow it in all your interactions with the project.
108
+
109
+ ## New contributor guide
110
+
111
+ To get an overview of the project, read the [documentation](https://jorgensd.github.io/adios4dolfinx). Here are some resources to help you get started with open source contributions:
112
+
113
+ - [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github)
114
+ - [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
115
+ - [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
116
+ - [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
117
+
118
+ ## Pull Request Process
119
+
120
+
121
+ ### Pull Request
122
+
123
+ - When you're finished with the changes, create a pull request, also known as a PR. It is also OK to create a [draft pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/) from the very beginning. Once you are done you can click on the ["Ready for review"] button. You can also [request a review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) from one of the maintainers.
124
+ - Don't forget to [link PR to the issue that you opened ](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).
125
+ - Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
126
+ Once you submit your PR, a team member will review your proposal. We may ask questions or request for additional information.
127
+ - We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
128
+ - As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
129
+ - If you run into any merge issues, checkout this [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) to help you resolve merge conflicts and other issues.
130
+ - Please make sure that all tests are passing, github pages renders nicely, and code coverage are are not lower than before your contribution. You see the different github action workflows by clicking the "Action" tab in the GitHub repository.
131
+
132
+ Note that for a pull request to be accepted, it has to pass all the tests on CI, which includes:
133
+ - `mypy`: typechecking
134
+ - `ruff`: Code formatting
135
+ - `pytest`: Successfull execution of all tests in the `tests` folder.
136
+
137
+
138
+ ### Our Pledge
139
+
140
+ In the interest of fostering an open and welcoming environment, we as
141
+ contributors and maintainers pledge to making participation in our project and
142
+ our community a harassment-free experience for everyone, regardless of age, body
143
+ size, disability, ethnicity, gender identity and expression, level of experience,
144
+ nationality, personal appearance, race, religion, or sexual identity and
145
+ orientation.
@@ -0,0 +1,113 @@
1
+ # ADIOS2Wrappers for DOLFINx
2
+
3
+ [![MIT](https://img.shields.io/github/license/jorgensd/adios4dolfinx)](LICENSE)
4
+ [Read Latest Documentation](https://jsdokken.com/adios4dolfinx/)
5
+
6
+ This is an extension for [DOLFINx](https://github.com/FEniCS/dolfinx/) to checkpoint meshes, meshtags and functions using [ADIOS2](https://adios2.readthedocs.io/en/latest/).
7
+
8
+ The code uses the adios2 Python-wrappers to write DOLFINx objects to file, supporting N-to-M (_recoverable_) and N-to-N (_snapshot_) checkpointing.
9
+ See: [Checkpointing in DOLFINx - FEniCS 23](https://jsdokken.com/checkpointing-presentation/#/) for more information.
10
+
11
+ For scalability, the code uses [MPI Neighbourhood collectives](https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report/node200.htm) for communication across processes.
12
+
13
+ ## Installation
14
+
15
+ ### Docker
16
+
17
+ ADIOS2 is installed in the official DOLFINx containers.
18
+
19
+ ```bash
20
+ docker run -ti -v $(pwd):/root/shared -w /root/shared --name=dolfinx-checkpoint ghcr.io/fenics/dolfinx/dolfinx:nightly
21
+ ```
22
+
23
+ ### Conda
24
+
25
+ To use with conda (DOLFINx release v0.7.0 works with v0.7.3 of ADIOS4DOLFINx)
26
+
27
+ ```bash
28
+ conda create -n dolfinx-checkpoint python=3.10
29
+ conda activate dolfinx-checkpoint
30
+ conda install -c conda-forge fenics-dolfinx pip adios2
31
+ python3 -m pip install git+https://github.com/jorgensd/adios4dolfinx@v0.7.2
32
+ ```
33
+
34
+ ## Functionality
35
+
36
+ ### DOLFINx
37
+
38
+ - Reading and writing meshes, using `adios4dolfinx.read/write_mesh`
39
+ - Reading and writing meshtags associated to meshes `adios4dolfinx.read/write_meshtags`
40
+ - Reading checkpoints for any element (serial and parallel, arbitrary number of functions and timesteps per file). Use `adios4dolfinx.read/write_function`.
41
+ - Writing standalone function checkpoints relating to "original meshes", i.e. meshes read from `XDMFFile`. Use `adios4dolfinx.write_function_on_input_mesh` for this.
42
+ - Store mesh partitioning and re-read the mesh with this information, avoiding calling SCOTCH, Kahip or Parmetis.
43
+
44
+ > [!IMPORTANT]
45
+ > For checkpoints written with `write_function` to be valid, you first have to store the mesh with `write_mesh` to the checkpoint file.
46
+
47
+ > [!IMPORTANT]
48
+ > A checkpoint file supports multiple functions and multiple time steps, as long as the functions are associated with the same mesh
49
+
50
+ > [!IMPORTANT]
51
+ > Only one mesh per file is allowed
52
+
53
+ ### Backwards compatibility
54
+
55
+ > [!WARNING]
56
+ > If you are using v0.7.2, you are adviced to upgrade to v0.7.3, as it contains som crucial fixes for openmpi.
57
+
58
+ ### Legacy DOLFIN
59
+
60
+ Only checkpoints for `Lagrange` or `DG` functions are supported from legacy DOLFIN
61
+
62
+ - Reading meshes from the DOLFIN HDF5File-format
63
+ - Reading checkpoints from the DOLFIN HDF5File-format (one checkpoint per file only)
64
+ - Reading checkpoints from the DOLFIN XDMFFile-format (one checkpoint per file only, and only uses the `.h5` file)
65
+
66
+ See the [API](./docs/api) for more information.
67
+
68
+ ## Long term plan
69
+
70
+ The long term plan is to get this library merged into DOLFINx (rewritten in C++ with appropriate Python-bindings).
71
+
72
+ # Contributor guidelines
73
+ When contributing to this repository, please first [create an issue](https://github.com/jorgensd/adios4dolfinx/issues/new/choose) containing information about the missing feature or the bug that you would like to fix. Here you can discuss the change you want to make with the maintainers of the repository.
74
+
75
+ Please note we have a code of conduct, please follow it in all your interactions with the project.
76
+
77
+ ## New contributor guide
78
+
79
+ To get an overview of the project, read the [documentation](https://jorgensd.github.io/adios4dolfinx). Here are some resources to help you get started with open source contributions:
80
+
81
+ - [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github)
82
+ - [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
83
+ - [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
84
+ - [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
85
+
86
+ ## Pull Request Process
87
+
88
+
89
+ ### Pull Request
90
+
91
+ - When you're finished with the changes, create a pull request, also known as a PR. It is also OK to create a [draft pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/) from the very beginning. Once you are done you can click on the ["Ready for review"] button. You can also [request a review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) from one of the maintainers.
92
+ - Don't forget to [link PR to the issue that you opened ](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).
93
+ - Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
94
+ Once you submit your PR, a team member will review your proposal. We may ask questions or request for additional information.
95
+ - We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
96
+ - As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
97
+ - If you run into any merge issues, checkout this [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) to help you resolve merge conflicts and other issues.
98
+ - Please make sure that all tests are passing, github pages renders nicely, and code coverage are are not lower than before your contribution. You see the different github action workflows by clicking the "Action" tab in the GitHub repository.
99
+
100
+ Note that for a pull request to be accepted, it has to pass all the tests on CI, which includes:
101
+ - `mypy`: typechecking
102
+ - `ruff`: Code formatting
103
+ - `pytest`: Successfull execution of all tests in the `tests` folder.
104
+
105
+
106
+ ### Our Pledge
107
+
108
+ In the interest of fostering an open and welcoming environment, we as
109
+ contributors and maintainers pledge to making participation in our project and
110
+ our community a harassment-free experience for everyone, regardless of age, body
111
+ size, disability, ethnicity, gender identity and expression, level of experience,
112
+ nationality, personal appearance, race, religion, or sexual identity and
113
+ orientation.
@@ -0,0 +1,68 @@
1
+ [build-system] # Require setuptool version due to https://github.com/pypa/setuptools/issues/2938
2
+ requires = ["setuptools>=61.0.0", "wheel"]
3
+
4
+ [project]
5
+ name = "adios4dolfinx"
6
+ version = "0.8.0.dev0"
7
+ description = "Checkpointing functionality for DOLFINx meshes/functions with ADIOS2"
8
+ authors = [{ name = "Jørgen S. Dokken", email = "dokken@simula.no" }]
9
+ license = { file = "LICENSE" }
10
+ readme = "README.md"
11
+ dependencies = ["fenics-dolfinx>=0.8.0.dev0"]
12
+
13
+ [project.optional-dependencies]
14
+ test = ["pytest", "coverage", "ipyparallel"]
15
+ dev = ["pdbpp", "ipython", "mypy", "ruff"]
16
+ docs = ["jupyter-book", "ipyparallel", "ipywidgets"]
17
+ all = ["adios4dolfinx[test,dev,docs]"]
18
+
19
+ [tool.pytest.ini_options]
20
+ addopts = ["--import-mode=importlib"]
21
+ testpaths = ["tests"]
22
+
23
+ [tool.mypy]
24
+ ignore_missing_imports = true
25
+ # Folders to exclude
26
+ exclude = ["docs/", "build/"]
27
+ # Folder to check with mypy
28
+ files = ["src", "tests"]
29
+
30
+ [tool.ruff]
31
+ src = ["src", "tests", "docs"]
32
+ line-length = 100
33
+ indent-width = 4
34
+
35
+ [tool.ruff.lint]
36
+ select = [
37
+ # Pyflakes
38
+ "F",
39
+ # Pycodestyle
40
+ "E",
41
+ "W",
42
+ # isort
43
+ "I001",
44
+ ]
45
+
46
+
47
+ [tool.ruff.lint.isort]
48
+ known-first-party = ["adios4dolfinx"]
49
+ known-third-party = [
50
+ "basix",
51
+ "dolfinx",
52
+ "ffcx",
53
+ "ufl",
54
+ "gmsh",
55
+ "numpy",
56
+ "pytest",
57
+ ]
58
+ section-order = [
59
+ "future",
60
+ "standard-library",
61
+ "mpi",
62
+ "third-party",
63
+ "first-party",
64
+ "local-folder",
65
+ ]
66
+
67
+ [tool.ruff.lint.isort.sections]
68
+ "mpi" = ["mpi4py", "petsc4py"]
@@ -5,13 +5,22 @@
5
5
  # SPDX-License-Identifier: MIT
6
6
 
7
7
  """Top-level package for ADIOS2Wrappers."""
8
+
8
9
  from importlib.metadata import metadata
9
10
 
10
- from .checkpointing import (read_function, read_mesh, read_meshtags,
11
- snapshot_checkpoint, write_function, write_mesh,
12
- write_meshtags)
13
- from .legacy_readers import (read_function_from_legacy_h5,
14
- read_mesh_from_legacy_h5)
11
+ from .checkpointing import (
12
+ read_attributes,
13
+ read_function,
14
+ read_mesh,
15
+ read_meshtags,
16
+ write_attributes,
17
+ write_function,
18
+ write_mesh,
19
+ write_meshtags,
20
+ )
21
+ from .legacy_readers import read_function_from_legacy_h5, read_mesh_from_legacy_h5
22
+ from .original_checkpoint import write_function_on_input_mesh, write_mesh_input_order
23
+ from .snapshot import snapshot_checkpoint
15
24
 
16
25
  meta = metadata("adios4dolfinx")
17
26
  __version__ = meta["Version"]
@@ -30,4 +39,8 @@ __all__ = [
30
39
  "write_function",
31
40
  "read_function",
32
41
  "snapshot_checkpoint",
42
+ "write_function_on_input_mesh",
43
+ "write_mesh_input_order",
44
+ "write_attributes",
45
+ "read_attributes",
33
46
  ]
@@ -0,0 +1,290 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import contextmanager
4
+ from pathlib import Path
5
+ from typing import NamedTuple
6
+
7
+ from mpi4py import MPI
8
+
9
+ import adios2
10
+ import dolfinx.cpp.graph
11
+ import dolfinx.graph
12
+ import numpy as np
13
+ import numpy.typing as npt
14
+
15
+ from .utils import compute_local_range, valid_function_types
16
+
17
+
18
+ def resolve_adios_scope(adios2):
19
+ return adios2.bindings if hasattr(adios2, "bindings") else adios2
20
+
21
+
22
+ adios2 = resolve_adios_scope(adios2)
23
+
24
+ """
25
+ Helpers reading/writing data with ADIOS2
26
+ """
27
+
28
+ __all__ = ["read_array", "read_adjacency_list", "read_cell_perms", "adios_to_numpy_dtype"]
29
+
30
+ adios_to_numpy_dtype = {
31
+ "float": np.float32,
32
+ "double": np.float64,
33
+ "float complex": np.complex64,
34
+ "double complex": np.complex128,
35
+ "uint32_t": np.uint32,
36
+ }
37
+
38
+
39
+ class AdiosFile(NamedTuple):
40
+ io: adios2.IO
41
+ file: adios2.Engine
42
+
43
+
44
+ @contextmanager
45
+ def ADIOSFile(
46
+ adios: adios2.ADIOS,
47
+ filename: Path | str,
48
+ engine: str,
49
+ mode: adios2.Mode,
50
+ io_name: str,
51
+ ):
52
+ io = adios.DeclareIO(io_name)
53
+ io.SetEngine(engine)
54
+ file = io.Open(str(filename), mode)
55
+ try:
56
+ yield AdiosFile(io=io, file=file)
57
+ finally:
58
+ file.Close()
59
+ adios.RemoveIO(io_name)
60
+
61
+
62
+ def read_cell_perms(
63
+ adios: adios2.ADIOS,
64
+ comm: MPI.Intracomm,
65
+ filename: Path | str,
66
+ variable: str,
67
+ num_cells_global: np.int64,
68
+ engine: str,
69
+ ) -> npt.NDArray[np.uint32]:
70
+ """
71
+ Read cell permutation from file with given communicator,
72
+ Split in continuous chunks based on number of cells in the mesh (global).
73
+
74
+ Args:
75
+ adios: The ADIOS instance
76
+ comm: The MPI communicator used to read the data
77
+ filename: Path to input file
78
+ variable: Name of cell-permutation variable
79
+ num_cells_global: Number of cells in the mesh (global)
80
+ engine: Type of ADIOS engine to use for reading data
81
+
82
+ Returns:
83
+ Cell-permutations local to the process
84
+
85
+ .. note::
86
+ No MPI communication is done during this call
87
+ """
88
+
89
+ # Open ADIOS engine
90
+ io_name = f"{variable=}_reader"
91
+
92
+ with ADIOSFile(
93
+ adios=adios,
94
+ engine=engine,
95
+ filename=filename,
96
+ mode=adios2.Mode.Read,
97
+ io_name=io_name,
98
+ ) as adios_file:
99
+ # Find step that has cell permutation
100
+ for i in range(adios_file.file.Steps()):
101
+ adios_file.file.BeginStep()
102
+ if variable in adios_file.io.AvailableVariables().keys():
103
+ break
104
+ adios_file.file.EndStep()
105
+ if variable not in adios_file.io.AvailableVariables().keys():
106
+ raise KeyError(f"Variable {variable} not found in '{filename}'")
107
+
108
+ # Get variable and get global shape
109
+ perm_var = adios_file.io.InquireVariable(variable)
110
+ shape = perm_var.Shape()
111
+ assert len(shape) == 1
112
+
113
+ # Get local selection
114
+ local_cell_range = compute_local_range(comm, num_cells_global)
115
+ perm_var.SetSelection([[local_cell_range[0]], [local_cell_range[1] - local_cell_range[0]]])
116
+ in_perm = np.empty(
117
+ local_cell_range[1] - local_cell_range[0],
118
+ dtype=adios_to_numpy_dtype[perm_var.Type()],
119
+ )
120
+ adios_file.file.Get(perm_var, in_perm, adios2.Mode.Sync)
121
+ adios_file.file.EndStep()
122
+
123
+ return in_perm
124
+
125
+
126
+ def read_adjacency_list(
127
+ adios: adios2.ADIOS,
128
+ comm: MPI.Intracomm,
129
+ filename: Path | str,
130
+ dofmap: str,
131
+ dofmap_offsets: str,
132
+ num_cells_global: np.int64,
133
+ engine: str,
134
+ ) -> dolfinx.cpp.graph.AdjacencyList_int64 | dolfinx.cpp.graph.AdjacencyList_int32:
135
+ """
136
+ Read an adjacency-list from an ADIOS file with given communicator.
137
+ The adjancency list is split in to a flat array (data) and its corresponding offset.
138
+
139
+ Args:
140
+ adios: The ADIOS instance
141
+ comm: The MPI communicator used to read the data
142
+ filename: Path to input file
143
+ dofmap: Name of variable containing dofmap
144
+ dofmap_offsets: Name of variable containing dofmap_offsets
145
+ num_cells_global: Number of cells in the mesh (global)
146
+ engine: Type of ADIOS engine to use for reading data
147
+
148
+ Returns:
149
+ The local part of dofmap from input dofs
150
+
151
+ .. note::
152
+ No MPI communication is done during this call
153
+ """
154
+ local_cell_range = compute_local_range(comm, num_cells_global)
155
+
156
+ # Open ADIOS engine
157
+ io_name = f"{dofmap=}_reader"
158
+
159
+ with ADIOSFile(
160
+ adios=adios,
161
+ engine=engine,
162
+ filename=filename,
163
+ mode=adios2.Mode.Read,
164
+ io_name=io_name,
165
+ ) as adios_file:
166
+ # First find step with dofmap offsets, to be able to read
167
+ # in a full row of the dofmap
168
+ for i in range(adios_file.file.Steps()):
169
+ adios_file.file.BeginStep()
170
+ if dofmap_offsets in adios_file.io.AvailableVariables().keys():
171
+ break
172
+ adios_file.file.EndStep()
173
+ if dofmap_offsets not in adios_file.io.AvailableVariables().keys():
174
+ raise KeyError(f"Dof offsets not found at '{dofmap_offsets}' in {filename}")
175
+
176
+ # Get global shape of dofmap-offset, and read in data with an overlap
177
+ d_offsets = adios_file.io.InquireVariable(dofmap_offsets)
178
+ shape = d_offsets.Shape()
179
+ assert len(shape) == 1
180
+ # As the offsets are one longer than the number of cells, we need to read in with an overlap
181
+ d_offsets.SetSelection(
182
+ [[local_cell_range[0]], [local_cell_range[1] + 1 - local_cell_range[0]]]
183
+ )
184
+ in_offsets = np.empty(
185
+ local_cell_range[1] + 1 - local_cell_range[0],
186
+ dtype=d_offsets.Type().strip("_t"),
187
+ )
188
+ adios_file.file.Get(d_offsets, in_offsets, adios2.Mode.Sync)
189
+
190
+ # Assuming dofmap is saved in stame step
191
+ # Get the relevant part of the dofmap
192
+ if dofmap not in adios_file.io.AvailableVariables().keys():
193
+ raise KeyError(f"Dof offsets not found at {dofmap} in {filename}")
194
+ cell_dofs = adios_file.io.InquireVariable(dofmap)
195
+ cell_dofs.SetSelection([[in_offsets[0]], [in_offsets[-1] - in_offsets[0]]])
196
+ in_dofmap = np.empty(in_offsets[-1] - in_offsets[0], dtype=cell_dofs.Type().strip("_t"))
197
+ adios_file.file.Get(cell_dofs, in_dofmap, adios2.Mode.Sync)
198
+ in_offsets -= in_offsets[0]
199
+
200
+ adios_file.file.EndStep()
201
+
202
+ # Return local dofmap
203
+ return dolfinx.graph.adjacencylist(in_dofmap, in_offsets.astype(np.int32))
204
+
205
+
206
+ def read_array(
207
+ adios: adios2.ADIOS,
208
+ filename: Path | str,
209
+ array_name: str,
210
+ engine: str,
211
+ comm: MPI.Intracomm,
212
+ time: float = 0.0,
213
+ time_name: str = "",
214
+ legacy: bool = False,
215
+ ) -> tuple[npt.NDArray[valid_function_types], int]:
216
+ """
217
+ Read an array from file, return the global starting position of the local array
218
+
219
+ Args:
220
+ adios: The ADIOS instance
221
+ filename: Path to file to read array from
222
+ array_name: Name of array in file
223
+ engine: Name of engine to use to read file
224
+ comm: MPI communicator used for reading the data
225
+ time_name: Name of time variable for modern checkpoints
226
+ legacy: If True ignore time_name and read the first available step
227
+ Returns:
228
+ Local part of array and its global starting position
229
+ """
230
+
231
+ with ADIOSFile(
232
+ adios=adios,
233
+ engine=engine,
234
+ filename=filename,
235
+ mode=adios2.Mode.Read,
236
+ io_name="ArrayReader",
237
+ ) as adios_file:
238
+ # Get time-stamp from first available step
239
+ if legacy:
240
+ for i in range(adios_file.file.Steps()):
241
+ adios_file.file.BeginStep()
242
+ if array_name in adios_file.io.AvailableVariables().keys():
243
+ break
244
+ adios_file.file.EndStep()
245
+ if array_name not in adios_file.io.AvailableVariables().keys():
246
+ raise KeyError(f"No array found at {array_name}")
247
+ else:
248
+ for i in range(adios_file.file.Steps()):
249
+ adios_file.file.BeginStep()
250
+ if time_name in adios_file.io.AvailableVariables().keys():
251
+ arr = adios_file.io.InquireVariable(time_name)
252
+ time_shape = arr.Shape()
253
+ arr.SetSelection([[0], [time_shape[0]]])
254
+ times = np.empty(time_shape[0], dtype=adios_to_numpy_dtype[arr.Type()])
255
+ adios_file.file.Get(arr, times, adios2.Mode.Sync)
256
+ if times[0] == time:
257
+ break
258
+ if i == adios_file.file.Steps() - 1:
259
+ raise KeyError(
260
+ f"No data associated with {time_name}={time} found in {filename}"
261
+ )
262
+
263
+ adios_file.file.EndStep()
264
+
265
+ if time_name not in adios_file.io.AvailableVariables().keys():
266
+ raise KeyError(f"No data associated with {time_name}={time} found in {filename}")
267
+
268
+ if array_name not in adios_file.io.AvailableVariables().keys():
269
+ raise KeyError(f"No array found at {time=} for {array_name}")
270
+
271
+ arr = adios_file.io.InquireVariable(array_name)
272
+ arr_shape = arr.Shape()
273
+ assert len(arr_shape) >= 1 # TODO: Should we always pick the first element?
274
+ arr_range = compute_local_range(comm, arr_shape[0])
275
+
276
+ if len(arr_shape) == 1:
277
+ arr.SetSelection([[arr_range[0]], [arr_range[1] - arr_range[0]]])
278
+ vals = np.empty(arr_range[1] - arr_range[0], dtype=adios_to_numpy_dtype[arr.Type()])
279
+ else:
280
+ arr.SetSelection([[arr_range[0], 0], [arr_range[1] - arr_range[0], arr_shape[1]]])
281
+ vals = np.empty(
282
+ (arr_range[1] - arr_range[0], arr_shape[1]),
283
+ dtype=adios_to_numpy_dtype[arr.Type()],
284
+ )
285
+ assert arr_shape[1] == 1
286
+
287
+ adios_file.file.Get(arr, vals, adios2.Mode.Sync)
288
+ adios_file.file.EndStep()
289
+
290
+ return vals.reshape(-1), arr_range[0]