Vue>> uvw>> 返回
项目作者: prs513rosewood

项目描述 :
Python package to write numpy arrays to VTK XML files
高级语言: Python
项目地址: git://github.com/prs513rosewood/uvw.git
创建时间: 2019-04-05T14:55:24Z
项目社区:https://github.com/prs513rosewood/uvw

开源协议:MIT License

下载


UVW - Universal VTK Writer

Build Status
Coverage
Status
PyPI Version

UVW is a small utility library to write XML VTK
files

from data contained in Numpy arrays. It handles fully-fledged ndarrays defined
over {1, 2, 3}-d domains, with arbitrary number of components. There are no
constraints on the particular order of components, although copy of data can be
avoided if the array is Fortran contiguous, as VTK files are written in Fortran
order. UVW supports multi-process writing of VTK files, so that it can be used
in an MPI environment.

Getting Started

Here is how to install and use uvw.

Prerequisites

  • Python 3. It may work with python 2, but it hasn’t been tested.
  • Numpy. This code has been tested with Numpy version
    1.14.3.
  • (Optional) mpi4py only if you wish to use the
    parallel classes of UVW (i.e. the submodule uvw.parallel)

Installing

This library can be installed with pip:

  1. pip install --user uvw

If you want to activate parallel capabilities, run:

  1. pip install --user uvw[mpi]

which will automatically pull mpi4py as a dependency.

Writing Numpy arrays

As a first example, let us write a multi-component numpy array into a
rectilinear grid:

  1. import numpy as np
  2. from uvw import RectilinearGrid, DataArray
  3. # Creating coordinates
  4. x = np.linspace(-0.5, 0.5, 10)
  5. y = np.linspace(-0.5, 0.5, 20)
  6. z = np.linspace(-0.9, 0.9, 30)
  7. # Creating the file (with possible data compression)
  8. grid = RectilinearGrid('grid.vtr', (x, y, z), compression=True)
  9. # A centered ball
  10. x, y, z = np.meshgrid(x, y, z, indexing='ij')
  11. r = np.sqrt(x**2 + y**2 + z**2)
  12. ball = r < 0.3
  13. # Some multi-component multi-dimensional data
  14. data = np.zeros([10, 20, 30, 3, 3])
  15. data[ball, ...] = np.array([[0, 1, 0],
  16. [1, 0, 0],
  17. [0, 1, 1]])
  18. # Some cell data
  19. cell_data = np.zeros([9, 19, 29])
  20. cell_data[0::2, 0::2, 0::2] = 1
  21. # Adding the point data (see help(DataArray) for more info)
  22. grid.addPointData(DataArray(data, range(3), 'ball'))
  23. # Adding the cell data
  24. grid.addCellData(DataArray(cell_data, range(3), 'checkers'))
  25. grid.write()

UVW also supports writing data on 2D and 1D physical domains, for example:

  1. import sys
  2. import numpy as np
  3. from uvw import RectilinearGrid, DataArray
  4. # Creating coordinates
  5. x = np.linspace(-0.5, 0.5, 10)
  6. y = np.linspace(-0.5, 0.5, 20)
  7. # A centered disk
  8. xx, yy = np.meshgrid(x, y, indexing='ij')
  9. r = np.sqrt(xx**2 + yy**2)
  10. R = 0.3
  11. disk = r < R
  12. data = np.zeros([10, 20])
  13. data[disk] = np.sqrt(1-(r[disk]/R)**2)
  14. # File object can be used as a context manager
  15. # and you can write to stdout!
  16. with RectilinearGrid(sys.stdout, (x, y)) as grid:
  17. grid.addPointData(DataArray(data, range(2), 'data'))

Writing in parallel with mpi4py

The classes contained in the uvw.parallel submodule support multi-process
writing using mpi4py. Here is a code example:

  1. import numpy as np
  2. from mpi4py import MPI
  3. from uvw.parallel import PRectilinearGrid
  4. from uvw import DataArray
  5. comm = MPI.COMM_WORLD
  6. rank = comm.Get_rank()
  7. N = 20
  8. # Domain bounds per rank
  9. bounds = [
  10. {'x': (-2, 0), 'y': (-2, 0)},
  11. {'x': (-2, 0), 'y': (0, 2)},
  12. {'x': (0, 2), 'y': (-2, 2)},
  13. ]
  14. # Domain sizes per rank
  15. sizes = [
  16. {'x': N, 'y': N},
  17. {'x': N, 'y': N},
  18. {'x': N, 'y': 2*N-1}, # account for overlap
  19. ]
  20. # Size offsets per rank
  21. offsets = [
  22. [0, 0],
  23. [0, N],
  24. [N, 0],
  25. ]
  26. x = np.linspace(*bounds[rank]['x'], sizes[rank]['x'])
  27. y = np.linspace(*bounds[rank]['y'], sizes[rank]['y'])
  28. xx, yy = np.meshgrid(x, y, indexing='ij', sparse=True)
  29. r = np.sqrt(xx**2 + yy**2)
  30. data = np.exp(-r**2)
  31. # Indicating rank info with a cell array
  32. proc = np.ones((x.size-1, y.size-1)) * rank
  33. with PRectilinearGrid('pgrid.pvtr', (x, y), offsets[rank]) as rect:
  34. rect.addPointData(DataArray(data, range(2), 'gaussian'))
  35. rect.addCellData(DataArray(proc, range(2), 'proc'))

As you can see, using PRectilinearGrid feels just like using
RectilinearGrid, except that you need to supply the position of the local grid
in the global grid numbering (the offsets[rank] in the above example). Note
that RecilinearGrid VTK files need an overlap in point data, hence why the
global grid size ends up being (2*N-1, 2*N-1). If you forget that overlap,
Paraview (or another VTK-based software) may complain that some parts in the
global grid (aka “extents” in VTK) are missing data.

Writing unstructured data

UVW supports VTK’s UnstructuredGrid, where the geometry is given with a list of
nodes and a connectivity. The UnstructuredGrid class expects connectivity to
be a dictionnary enumerating the different connectivity types and the cells
associated to each type. For example:

  1. import numpy as np
  2. from uvw import UnstructuredGrid
  3. from uvw.unstructured import CellType
  4. nodes = np.array([
  5. [0, 0, 0],
  6. [1, 0, 0],
  7. [1, 1, 0],
  8. [0, 1, 0],
  9. [2, 0, 0],
  10. [0, 2, 0],
  11. [1, 2, 0],
  12. ])
  13. connectivity = {
  14. CellType.QUAD: np.array([
  15. [0, 1, 2, 3], [2, 6, 5, 3],
  16. ]),
  17. 5: np.array([[4, 2, 1]]),
  18. }
  19. f = UnstructuredGrid('ugrid.vtu', nodes, connectivity)
  20. f.write()

As you can see, cell types can be specified with the unstructured.CellType
enumeration or with the underlying integer value (see
VTKFileFormats
for more info). UnstructuredGrid performs a sanity check of the connectivity
to see if the number of nodes matches the cell type.

If you work with large amounts of unstructured data, consider checking out
meshio which provides many different
read/write capabilities for various unstructured formats, some of which are
supported by VTK and are better than VTK’s simple XML format.

List of features

Here is a list of what is available in UVW:

VTK file formats

  • Image data (.vti)
  • Rectilinear grid (.vtr)
  • Structured grid (.vts)
  • Unstructured grid (.vtu)
  • Parallel Rectilinear grid (.pvtr)
  • Parallel Image data (.pvti)
  • ParaView Data (.pvd)

Data representation

  • ASCII
  • Base64 (raw and compressed: the compression argument of file constructors
    can be True, False, or an integer in [-1, 9] for compression levels)

Note that raw binary data, while more space efficient and supported by VTK,
is not valid XML, and therefore not supported by UVW, which uses minidom for XML
writing.

PyEVTK high-level API implementation

To facilitate transition from
PyEVTK, UVW implements a part of
its API, without imposing restrictions on data (such as the number of components
per array) and allowing data compression. Simply replace import pyevtk.hl by
import uvw.dropin.hl. To enable compression, provide compression=True to any
of the functions in uvw.dropin.hl. Note: the drop-in is not automatically
tested, do not hesitate to report problems.

Planned developments

Here is a list of future developments:

  • Image data
  • Unstructured grid
  • Structured grid
  • Parallel writing (mpi4py-enabled PRectilinearGrid and PImageData
    1. *are now available!*)
  • Benchmarking + performance comparison with
    1. [pyevtk](https://github.com/pyscience-projects/pyevtk)

Developing

These instructions will get you a copy of the project up and running on your
local machine for development and testing purposes.

Git repository

First clone the git repository:

  1. git clone https://github.com/prs513rosewood/uvw.git

Then you can use pip in development mode (possibly in
virtualenv):

  1. pip install --user -e .[mpi,tests]

Installing with the tests extra pulls vtk as a dependency. This is because
reading files with VTK in tests is the most reliable way to check file
integrity.

Running the tests

The tests can be run using pytest:

  1. pytest
  2. # or for tests with mpi
  3. mpiexec -n 2 pytest --with-mpi

License

This project is licensed under the MIT License - see the LICENSE.md file for
details.

Acknowledgments