Coverage for / dolfinx-env / lib / python3.12 / site-packages / io4dolfinx / backends / __init__.py: 89%
37 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-26 18:16 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-26 18:16 +0000
1from enum import Enum
2from importlib import import_module
3from pathlib import Path
4from typing import Any, Protocol
6from mpi4py import MPI
8import dolfinx
9import numpy as np
10import numpy.typing as npt
12from ..structures import ArrayData, FunctionData, MeshData, MeshTagsData, ReadMeshData
14__all__ = ["FileMode", "IOBackend", "get_backend"]
17class ReadMode(Enum):
18 serial = 10 # This means that all data is read in on root rank
20 # Total number of data P, num processes = i + 1.
21 # All processes reads at least `P // (i+1)` items
22 # The first j=P%(i+1) processes reads `P // (i+1) + 1` items
23 # ```python
24 # def compute_partitioning(P, J):
25 # min_num = P // J
26 # num_per_proc = np.full(J, min_num)
27 # rem = P % J
28 # num_per_proc[:int(rem)] += 1
29 # assert(sum(num_per_proc)) == P
30 # return num_per_proc
31 # ```
32 parallel = 20
35class FileMode(Enum):
36 """Filen mode used for opening files."""
38 append = 10 #: Append data to file
39 write = 20 #: Write data to file
40 read = 30 #: Read data from file
43# See https://peps.python.org/pep-0544/#modules-as-implementations-of-protocols
44class IOBackend(Protocol):
45 read_mode: ReadMode
47 def get_default_backend_args(self, arguments: dict[str, Any] | None) -> dict[str, Any]:
48 """Get default backend arguments given a set of input arguments.
50 Args:
51 arguments: Input backend arguments
53 Returns:
54 Updated backend arguments
55 """
57 def write_attributes(
58 self,
59 filename: Path | str,
60 comm: MPI.Intracomm,
61 name: str,
62 attributes: dict[str, np.ndarray],
63 backend_args: dict[str, Any] | None,
64 ):
65 """Write attributes to file.
67 Args:
68 filename: Path to file to write to
69 comm: MPI communicator used in storage
70 name: Name of the attribute group
71 attributes: Dictionary of attributes to write
72 backend_args: Arguments to backend
73 """
75 def read_attributes(
76 self,
77 filename: Path | str,
78 comm: MPI.Intracomm,
79 name: str,
80 backend_args: dict[str, Any] | None,
81 ) -> dict[str, Any]:
82 """Read attributes from file.
84 Args:
85 filename: Path to file to read from
86 comm: MPI communicator used in storage
87 name: Name of the attribute group
88 backend_args: Arguments to backend
90 Returns:
91 Dictionary of attributes read from file
92 """
94 def read_timestamps(
95 self,
96 filename: Path | str,
97 comm: MPI.Intracomm,
98 function_name: str,
99 backend_args: dict[str, Any] | None,
100 ) -> npt.NDArray[np.float64 | str]: # type: ignore[type-var]
101 """Read timestamps from file.
103 Args:
104 filename: Path to file to read from
105 comm: MPI communicator used in storage
106 function_name: Name of the function to read timestamps for
107 backend_args: Arguments to backend
109 Returns:
110 Numpy array of timestamps read from file
111 """
113 def write_mesh(
114 self,
115 filename: Path | str,
116 comm: MPI.Intracomm,
117 mesh: MeshData,
118 backend_args: dict[str, Any] | None,
119 mode: FileMode,
120 time: float,
121 ):
122 """
123 Write a mesh to file.
125 Args:
126 comm: MPI communicator used in storage
127 mesh: Internal data structure for the mesh data to save to file
128 filename: Path to file to write to
129 backend_args: Arguments to backend
130 mode: File-mode to store the mesh
131 time: Time stamp associated with the mesh
132 """
134 def write_meshtags(
135 self,
136 filename: str | Path,
137 comm: MPI.Intracomm,
138 data: MeshTagsData,
139 backend_args: dict[str, Any] | None,
140 ):
141 """Write mesh tags to file.
143 Args:
144 filename: Path to file to write to
145 comm: MPI communicator used in storage
146 data: Internal data structure for the mesh tags to save to file
147 backend_args: Arguments to backend
148 """
150 def read_mesh_data(
151 self,
152 filename: Path | str,
153 comm: MPI.Intracomm,
154 time: str | float | None,
155 read_from_partition: bool,
156 backend_args: dict[str, Any] | None,
157 ) -> ReadMeshData:
158 """Read mesh data from file.
160 Args:
161 filename: Path to file to read from
162 comm: MPI communicator used in storage
163 time: Time stamp associated with the mesh to read
164 read_from_partition: Whether to read partition information
165 backend_args: Arguments to backend
167 Returns:
168 Internal data structure for the mesh data read from file
169 """
171 def read_meshtags_data(
172 self,
173 filename: str | Path,
174 comm: MPI.Intracomm,
175 name: str,
176 backend_args: dict[str, Any] | None,
177 ) -> MeshTagsData:
178 """Read mesh tags from file.
180 Args:
181 filename: Path to file to read from
182 comm: MPI communicator used in storage
183 name: Name of the mesh tags to read
184 backend_args: Arguments to backend
186 Returns:
187 Internal data structure for the mesh tags read from file
188 """
190 def read_dofmap(
191 self,
192 filename: str | Path,
193 comm: MPI.Intracomm,
194 name: str,
195 backend_args: dict[str, Any] | None,
196 ) -> dolfinx.graph.AdjacencyList:
197 """Read the dofmap of a function with a given name.
199 Args:
200 filename: Path to file to read from
201 comm: MPI communicator used in storage
202 name: Name of the function to read the dofmap for
203 backend_args: Arguments to backend
205 Returns:
206 Dofmap as an {py:class}`dolfinx.graph.AdjacencyList`
207 """
209 def read_dofs(
210 self,
211 filename: str | Path,
212 comm: MPI.Intracomm,
213 name: str,
214 time: float,
215 backend_args: dict[str, Any] | None,
216 ) -> tuple[npt.NDArray[np.float32 | np.float64 | np.complex64 | np.complex128], int]:
217 """Read the dofs (values) of a function with a given name from a given timestep.
219 Args:
220 filename: Path to file to read from
221 comm: MPI communicator used in storage
222 name: Name of the function to read the dofs for
223 time: Time stamp associated with the function to read
224 backend_args: Arguments to backend
226 Returns:
227 Contiguous sequence of degrees of freedom (with respect to input data)
228 and the global starting point on the process.
229 Process 0 has [0, M), process 1 [M, N), process 2 [N, O) etc.
230 """
232 def read_cell_perms(
233 self, comm: MPI.Intracomm, filename: Path | str, backend_args: dict[str, Any] | None
234 ) -> npt.NDArray[np.uint32]:
235 """
236 Read cell permutation from file with given communicator,
237 Split in continuous chunks based on number of cells in the input data.
239 Args:
240 comm: MPI communicator used in storage
241 filename: Path to file to read from
242 backend_args: Arguments to backend
244 Returns:
245 Contiguous sequence of permutations (with respect to input data)
246 Process 0 has [0, M), process 1 [M, N), process 2 [N, O) etc.
247 """
249 def write_function(
250 self,
251 filename: Path,
252 comm: MPI.Intracomm,
253 u: FunctionData,
254 time: float,
255 mode: FileMode,
256 backend_args: dict[str, Any] | None,
257 ):
258 """Write a function to file.
260 Args:
261 comm: MPI communicator used in storage
262 u: Internal data structure for the function data to save to file
263 filename: Path to file to write to
264 time: Time stamp associated with function
265 mode: File-mode to store the function
266 backend_args: Arguments to backend
267 """
269 def read_legacy_mesh(
270 self, filename: Path | str, comm: MPI.Intracomm, group: str
271 ) -> tuple[npt.NDArray[np.int64], npt.NDArray[np.floating], str | None]:
272 """Read in the mesh topology, geometry and (optionally) cell type from a
273 legacy DOLFIN HDF5-file.
275 Args:
276 filename: Path to file to read from
277 comm: MPI communicator used in storage
278 group: Group in HDF5 file where mesh is stored
280 Returns:
281 Tuple containing:
282 - Topology as a (num_cells, num_vertices_per_cell) array of global vertex indices
283 - Geometry as a (num_vertices, geometric_dimension) array of vertex coordinates
284 - Cell type as a string (e.g. "tetrahedron") or None if not found
285 """
287 def snapshot_checkpoint(
288 self,
289 filename: Path | str,
290 mode: FileMode,
291 u: dolfinx.fem.Function,
292 backend_args: dict[str, Any] | None,
293 ):
294 """Create a snapshot checkpoint of a dolfinx function.
296 Args:
297 filename: Path to file to read from
298 mode: File-mode to store the function
299 u: dolfinx function to create a snapshot checkpoint for
300 backend_args: Arguments to backend
301 """
303 def read_hdf5_array(
304 self,
305 comm: MPI.Intracomm,
306 filename: Path | str,
307 group: str,
308 backend_args: dict[str, Any] | None,
309 ) -> tuple[np.ndarray, int]:
310 """Read an array from an HDF5 file.
312 Args:
313 comm: MPI communicator used in storage
314 filename: Path to file to read from
315 group: Group in HDF5 file where array is stored
316 backend_args: Arguments to backend
318 Returns:
319 Tuple containing:
320 - Numpy array read from file
321 - Global starting point on the process.
322 Process 0 has [0, M), process 1 [M, N), process 2 [N, O) etc.
323 """
325 def read_point_data(
326 self,
327 filename: Path | str,
328 name: str,
329 comm: MPI.Intracomm,
330 time: str | float | None,
331 backend_args: dict[str, Any] | None,
332 ) -> tuple[np.ndarray, int]:
333 """Read data from the nodes of a mesh.
335 Args:
336 filename: Path to file
337 name: Name of point data
338 comm: Communicator to launch IO on.
339 time: The time stamp
340 backend_args: The backend arguments
341 Returns:
342 Data local to process (contiguous, no mpi comm) and local start range
343 """
344 ...
346 def read_function_names(
347 self, filename: Path | str, comm: MPI.Intracomm, backend_args: dict[str, Any] | None
348 ) -> list[str]:
349 """Read all function names from a file.
351 Args:
352 filename: Path to file
353 comm: MPI communicator to launch IO on.
354 backend_args: Arguments to backend
356 Returns:
357 A list of function names.
358 """
359 ...
361 def read_cell_data(
362 self,
363 filename: Path | str,
364 name: str,
365 comm: MPI.Intracomm,
366 time: str | float | None,
367 backend_args: dict[str, Any] | None,
368 ) -> tuple[npt.NDArray[np.int64], np.ndarray]:
369 """Read data from the cells of a mesh.
371 Args:
372 filename: Path to file
373 name: Name of point data
374 comm: Communicator to launch IO on.
375 time: The time stamp
376 backend_args: The backend arguments
377 Returns:
378 A tuple (topology, dofs) where topology contains the
379 vertex indices of the cells, dofs the degrees of
380 freedom within that cell.
381 """
382 ...
384 def write_data(
385 self,
386 filename: Path | str,
387 array_data: ArrayData,
388 comm: MPI.Intracomm,
389 time: str | float | None,
390 mode: FileMode,
391 backend_args: dict[str, Any] | None,
392 ):
393 """Write a 2D-array to file.
396 Args:
397 filename: Path to file
398 array_data: Data to write to file.
399 comm: The MPI communicator to open the writer with.
400 time: The time stamp
401 mode: Append or write
402 backend_args: The backend arguments
403 """
404 ...
407def get_backend(backend: str) -> IOBackend:
408 """Get backend class from backend name.
410 Args:
411 backend: Name of the backend to get
413 Returns:
414 Backend class
415 """
416 if backend == "h5py":
417 from .h5py import backend as H5PYInterface
419 return H5PYInterface
420 elif backend == "adios2":
421 from .adios2 import backend as ADIOS2Interface
423 return ADIOS2Interface
424 elif backend == "pyvista":
425 from .pyvista import backend as PYVISTAInterface
427 return PYVISTAInterface
428 elif backend == "xdmf":
429 from .xdmf import backend as XDMFInterface
431 return XDMFInterface
432 elif backend == "vtkhdf":
433 from .vtkhdf import backend as VTKDHFInterface
435 return VTKDHFInterface
436 elif backend == "exodus":
437 from .exodus import backend as EXODUSInterface
439 return EXODUSInterface
440 else:
441 return import_module(backend)