Compute Gradients of a Field

Compute Gradients of a Field#

Estimate the gradient of a scalar or vector field in a data set.

The ordering for the output gradient tuple will be {du/dx, du/dy, du/dz, dv/dx, dv/dy, dv/dz, dw/dx, dw/dy, dw/dz} for an input array {u, v, w}.

Showing the pyvista.DataSetFilters.compute_derivative() filter.

from __future__ import annotations

import numpy as np

import pyvista as pv
from pyvista import examples

# A vtkStructuredGrid - but could be any mesh type
mesh = examples.download_carotid()
mesh
HeaderData Arrays
ImageDataInformation
N Cells158400
N Points167580
X Bounds1.000e+02, 1.750e+02
Y Bounds8.000e+01, 1.280e+02
Z Bounds1.000e+00, 4.500e+01
Dimensions76, 49, 45
Spacing1.000e+00, 1.000e+00, 1.000e+00
N Arrays2
NameFieldTypeN CompMinMax
scalarsPointsfloat3210.000e+005.800e+02
vectorsPointsfloat323-2.263e+011.662e+01


Now compute the gradients of the vectors vector field in the point data of that mesh. This is as simple as calling pyvista.DataSetFilters.compute_derivative().

mesh_g = mesh.compute_derivative(scalars='vectors')
mesh_g['gradient']
pyvista_ndarray([[  7.21899979e-03,   7.65699986e-03,   3.87999974e-03,
                  ...,  -7.38500012e-03,   1.00600009e-03,  -2.10000435e-05],
                 [  4.28850017e-03,   9.30000097e-04,  -6.55200006e-03,
                  ...,  -6.13999972e-03,   3.67700006e-03,   1.17300004e-02],
                 [  5.40149957e-03,   1.25399977e-03,  -4.65100026e-03,
                  ...,   3.49000096e-04,   8.01400002e-03,   8.14399961e-03],
                 ...,
                 [ -6.39999984e-04,  -2.63400003e-03,   6.17399998e-03,
                  ...,  -4.32049995e-03,  -1.22299988e-03,  -1.89600000e-03],
                 [ -1.59000000e-03,  -3.44600016e-03,   4.12799977e-03,
                  ...,  -2.89999996e-03,  -5.99600002e-03,  -5.81400003e-03],
                 [ -9.11999959e-04,  -4.06700000e-03,  -1.58199994e-03,
                  ...,  -2.47599976e-03,  -8.52899998e-03,  -5.39399963e-03]], dtype=float32)

Note

You can also use pyvista.DataSetFilters.compute_derivative() for computing other derivative based quantities, such as divergence, vorticity, and Q-criterion. See function documentation for options.

mesh_g["gradient"] is an N by 9 NumPy array of the gradients, so we could make a dictionary of NumPy arrays of the gradients like:

def gradients_to_dict(arr):
    """Label the gradients into a dictionary."""
    keys = np.array(
        ['du/dx', 'du/dy', 'du/dz', 'dv/dx', 'dv/dy', 'dv/dz', 'dw/dx', 'dw/dy', 'dw/dz'],
    )
    keys = keys.reshape((3, 3))[:, : arr.shape[1]].ravel()
    return dict(zip(keys, mesh_g['gradient'].T))


gradients = gradients_to_dict(mesh_g['gradient'])
gradients
{'du/dx': pyvista_ndarray([ 0.007219 ,  0.0042885,  0.0054015, ..., -0.00064  ,
                 -0.00159  , -0.000912 ], dtype=float32), 'du/dy': pyvista_ndarray([ 0.007657,  0.00093 ,  0.001254, ..., -0.002634,
                 -0.003446, -0.004067], dtype=float32), 'du/dz': pyvista_ndarray([ 0.00388 , -0.006552, -0.004651, ...,  0.006174,
                  0.004128, -0.001582], dtype=float32), 'dv/dx': pyvista_ndarray([ -7.59999966e-04,  -1.05850003e-03,  -2.95999995e-03, ...,
                  -1.95549987e-03,   9.99998883e-06,   2.66000000e-03], dtype=float32), 'dv/dy': pyvista_ndarray([ 0.000226, -0.00503 , -0.003388, ..., -0.0059  ,
                 -0.008274, -0.000512], dtype=float32), 'dv/dz': pyvista_ndarray([-0.006821, -0.000382,  0.006909, ..., -0.001991,
                 -0.003061, -0.00189 ], dtype=float32), 'dw/dx': pyvista_ndarray([-0.007385 , -0.00614  ,  0.000349 , ..., -0.0043205,
                 -0.0029   , -0.002476 ], dtype=float32), 'dw/dy': pyvista_ndarray([ 0.001006,  0.003677,  0.008014, ..., -0.001223,
                 -0.005996, -0.008529], dtype=float32), 'dw/dz': pyvista_ndarray([ -2.10000435e-05,   1.17300004e-02,   8.14399961e-03, ...,
                  -1.89600000e-03,  -5.81400003e-03,  -5.39399963e-03], dtype=float32)}

And we can add all of those components as individual arrays back to the mesh by:

HeaderData Arrays
ImageDataInformation
N Cells158400
N Points167580
X Bounds1.000e+02, 1.750e+02
Y Bounds8.000e+01, 1.280e+02
Z Bounds1.000e+00, 4.500e+01
Dimensions76, 49, 45
Spacing1.000e+00, 1.000e+00, 1.000e+00
N Arrays12
NameFieldTypeN CompMinMax
scalarsPointsfloat3210.000e+005.800e+02
vectorsPointsfloat323-2.263e+011.662e+01
gradientPointsfloat329-1.585e+011.536e+01
du/dxPointsfloat321-8.293e+008.336e+00
du/dyPointsfloat321-1.084e+018.334e+00
du/dzPointsfloat321-8.300e+008.317e+00
dv/dxPointsfloat321-1.133e+011.536e+01
dv/dyPointsfloat321-1.585e+011.170e+01
dv/dzPointsfloat321-1.131e+017.459e+00
dw/dxPointsfloat321-8.738e+001.212e+01
dw/dyPointsfloat321-8.734e+008.740e+00
dw/dzPointsfloat321-1.124e+018.728e+00


keys = np.array(list(gradients.keys())).reshape(3, 3)

p = pv.Plotter(shape=keys.shape)
for (i, j), name in np.ndenumerate(keys):
    p.subplot(i, j)
    p.add_mesh(mesh_g.contour(scalars=name), scalars=name, opacity=0.75)
    p.add_mesh(mesh_g.outline(), color='k')
p.link_views()
p.view_isometric()
p.show()
gradients

And there you have it, the gradients for a vector field. We could also do this for a scalar field like for the scalars field in the given dataset.

mesh_g = mesh.compute_derivative(scalars='scalars')

gradients = gradients_to_dict(mesh_g['gradient'])
gradients
{'du/dx': pyvista_ndarray([-7. , -7. , -4. , ..., -0.5, -1.5, -2. ], dtype=float32), 'du/dy': pyvista_ndarray([  0.,   5.,  12., ...,  -3.,  -1.,  -3.], dtype=float32), 'du/dz': pyvista_ndarray([-13.,  -8.,  -3., ...,   4.,   4.,   1.], dtype=float32)}
gradients

Tags: filter

Total running time of the script: (0 minutes 3.425 seconds)

Gallery generated by Sphinx-Gallery