Computing Mesh Quality#

Leverage powerful VTK algorithms for computing mesh quality.

Here we will use the cell_quality() filter to compute the cell qualities. The following quality measures are available for various cell types:

Cell Quality Measures#

Measure

TRIANGLE

QUAD

TETRA

HEXAHEDRON

PYRAMID

WEDGE

area

aspect_frobenius

aspect_gamma

aspect_ratio

collapse_ratio

condition

diagonal

dimension

distortion

jacobian

max_angle

max_aspect_frobenius

max_edge_ratio

med_aspect_frobenius

min_angle

oddy

radius_ratio

relative_size_squared

scaled_jacobian

shape

shape_and_size

shear

shear_and_size

skew

stretch

taper

volume

warpage

from __future__ import annotations

import pyvista as pv
from pyvista import examples

Triangle Cell Quality#

Load a PolyData mesh and decimate() it to show coarse TRIANGLE cells for the example. Here we use download_cow().

mesh = examples.download_cow().triangulate().decimate(0.7)

Compute some valid measures for triangle cells.

measures = ['area', 'shape', 'min_angle', 'max_angle']
qual = mesh.cell_quality(measures)

Plot the meshes in subplots for comparison. We define a custom method for adding each mesh to each subplot.

def add_mesh(plotter, mesh, scalars=None, cmap='bwr', show_edges=True):
    # Create a copy to avoid reusing the same mesh in different plots
    copied = mesh.copy(deep=False)
    plotter.add_mesh(copied, scalars=scalars, cmap=cmap, show_edges=show_edges)
    plotter.view_xy()


pl = pv.Plotter(shape=(2, 2))
pl.link_views()
pl.subplot(0, 0)
add_mesh(pl, qual, scalars=measures[0])
pl.subplot(0, 1)
add_mesh(pl, qual, scalars=measures[1])
pl.subplot(1, 0)
add_mesh(pl, qual, scalars=measures[2])
pl.subplot(1, 1)
add_mesh(pl, qual, scalars=measures[3])
pl.show()
mesh quality

Visualize Acceptable Range#

The previous plots show the full range of cell quality values present in the mesh. However, it may be more useful to show the acceptable range of values instead. Get the acceptable range for the shape quality measure using cell_quality_info().

info = pv.cell_quality_info('TRIANGLE', 'shape')
print(info)
CellQualityInfo(cell_type=<CellType.TRIANGLE: 5>, quality_measure='shape', acceptable_range=(0.25, 1.0), normal_range=(0.0, 1.0), full_range=(0.0, 1.0), unit_cell_value=1.0)

Plot the shape quality measure again but this time we color the cells based on the acceptable range for the measure. Cells outside of this range are saturated as blue or red and may be considered to be “poor” quality cells.

qual.plot(
    scalars='shape',
    clim=info.acceptable_range,
    cmap='bwr',
    below_color='blue',
    above_color='red',
    cpos='xy',
    zoom=1.5,
    show_axes=False,
)
mesh quality

Use extract_values() to extract the “poor” quality cells outside the acceptable range.

unacceptable = qual.extract_values(scalars='shape', ranges=info.acceptable_range, invert=True)

Plot the unacceptable cells along with the original mesh as wireframe for context.

pl = pv.Plotter()
pl.add_mesh(mesh, style='wireframe', color='light gray')
pl.add_mesh(unacceptable, color='lime')
pl.view_xy()
pl.camera.zoom(1.5)
pl.show()
mesh quality

Tetrahedron Cell Quality#

Load a mesh with TETRA cells. Here we use download_letter_a().

mesh = examples.download_letter_a()

Plot some valid quality measures for tetrahedral cells.

measures = ['volume', 'collapse_ratio', 'jacobian', 'scaled_jacobian']
qual = mesh.cell_quality(measures)

pl = pv.Plotter(shape=(2, 2))
pl.link_views()
pl.subplot(0, 0)
add_mesh(pl, qual, scalars=measures[0])
pl.subplot(0, 1)
add_mesh(pl, qual, scalars=measures[1])
pl.subplot(1, 0)
add_mesh(pl, qual, scalars=measures[2])
pl.subplot(1, 1)
add_mesh(pl, qual, scalars=measures[3])
pl.show()
mesh quality

Tags: filter

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

Gallery generated by Sphinx-Gallery