Mesh diagnostics#

Mesh statistics and quality#

You can use a set of quality metrics to measure the mesh quality. The SurfaceSearch and VolumeSearch classes allow you to verify surface and volume mesh quality, respectively.

Connectivity checks#

Surface diagnostics are important prior to generating a volume mesh. You can get a surface diagnostic summary by using the SurfaceSearch.get_surface_diagnostic_summary() method. The SurfaceDiagnosticSummaryParams class provides for diagnosing surface connectivity for the given scope and controls:

  • Duplicate faces

  • Free face edges

  • Multi face edges

  • Self intersections

This code determines if a wrap surface is closed:

# Check if wrap surface is closed
scope = prime.ScopeDefinition(model=model, part_expression="wrap")
diag = prime.SurfaceSearch(model)

diag_params = prime.SurfaceDiagnosticSummaryParams(
    model,
    scope=scope,
    compute_duplicate_faces=True,
    compute_free_edges=True,
    compute_multi_edges=True,
    compute_self_intersections=True,
)

diag_res = diag.get_surface_diagnostic_summary(diag_params)

This code prints the results of the surface diagnostic summary:

>>> print("Number of duplicate faces : ", diag_res.n_duplicate_faces)
>>> print("Number of free edges : ", diag_res.n_free_edges)
>>> print("Number of multi edges : ", diag_res.n_multi_edges)
>>> print("Number of self intersections : ", diag_res.n_self_intersections)

Number of duplicate faces :  0
Number of free edges :  0
Number of multi edges :  0
Number of self intersections :  0

Face metrics#

The FaceQualityMeasure class offers various types of measures to verify face quality metrics.

  • The SKEWNESS metric ranges between 0 (ideal) and 1 (worst).

  • The ASPECTRATIO metric is greater than 1. The smaller the aspect ratio, the higher the quality of an element.

  • The ELEMENTQUALITY metric ranges between 0 (worst) and 1 (ideal).

This code gets face quality measures:

face_quality_measures = prime.FaceQualityMeasure.SKEWNESS
quality = prime.SurfaceSearch(model)
quality_params = prime.SurfaceQualitySummaryParams(
    model=model,
    scope=prime.ScopeDefinition(model=model, part_expression="wrap"),
    face_quality_measures=[face_quality_measures],
    quality_limit=[0.9],
)
qual_summary_res = quality.get_surface_quality_summary(quality_params)

This code prints face quality summary results:

>>> print("Maximum surface skewness : ", qual_summary_res.quality_results[0].max_quality)
>>> print("Number of faces above limit : ", qual_summary_res.quality_results[0].n_found)

Maximum surface skewness :  0.862375
Number of faces above limit :  0

Cell metrics#

The CellQualityMeasure class offers various types of measures to verify cell quality metrics.

  • The SKEWNESS metric ranges between 0 (ideal) and 1 (worst).

  • The ASPECTRATIO metric is greater than 1. The smaller the aspect ratio, the higher the quality of an element.

  • The FLUENTASPECTRATIO metric is greater than 1. The smaller the Fluent aspect ratio, the higher the quality of an element.

  • The ELEMENTQUALITY metric ranges between 0 (worst) and 1 (ideal).

This code gets cell quality measures:

cell_quality_measures = prime.CellQualityMeasure.SKEWNESS
quality = prime.VolumeSearch(model)
quality_params = prime.VolumeQualitySummaryParams(
    model=model,
    scope=prime.ScopeDefinition(model=model, part_expression="wrap"),
    cell_quality_measures=[cell_quality_measures],
    quality_limit=[0.95],
)
qual_summary_res = quality.get_volume_quality_summary(quality_params)

This code prints cell quality summary results:

>>> print("Maximum skewness : ", qual_summary_res.quality_results_part[0].max_quality)
>>> print(
...     "Number of cells above limit : ", qual_summary_res.quality_results_part[0].n_found
... )

Maximum skewness :  0.948388
Number of cells above limit :  0

Mesh counts#

The Part.get_summary() method provides the number of nodes, faces, or cells after meshing with the given parameters.

This code gets mesh counts:

part_summary_res = part.get_summary(
    prime.PartSummaryParams(model=model, print_id=False, print_mesh=True)
)

This code prints mesh counts:

>>> print("Number of tri faces : ", part_summary_res.n_tri_faces)
>>> print("Number of tet cells : ", part_summary_res.n_tet_cells)
>>> print("Number of poly cells : ", part_summary_res.n_poly_cells)
>>> print("Total number of cells : ", part_summary_res.n_cells)

Number of tri faces :  49430
Number of tet cells :  254669
Number of poly cells :  82760
Total number of cells :  337429

Mesh improvement#

When the metrics show that the mesh quality is low, the VolumeMeshTool class provides various volume mesh improvement algorithms for improving the mesh.

Auto node move#

You can improve volume mesh by auto node move using the VolumeMeshTool.improve_by_auto_node_move() method with given parameters. In addition, you can verify the mesh using the VolumeMeshTool.check_mesh() method.

This code improves and checks the volume mesh:

# Auto node move
perform_anm = prime.VolumeMeshTool(model=model)
anm_params = prime.AutoNodeMoveParams(
    model=model,
    quality_measure=prime.CellQualityMeasure.SKEWNESS,
    target_quality=0.95,
    dihedral_angle=90,
    n_iterations_per_node=50,
    restrict_boundary_nodes_along_surface=True,
    n_attempts=10,
)

perform_anm.improve_by_auto_node_move(
    part_id=part.id,
    cell_zonelets=part.get_cell_zonelets(),
    boundary_zonelets=part.get_face_zonelets(),
    params=anm_params,
)

# Mesh checking
vtool = prime.VolumeMeshTool(model=model)
res = vtool.check_mesh(part_id=part.id, params=prime.CheckMeshParams(model=model))

This code prints the results of checking mesh operation:

>>> print("Non positive volumes:", result.has_non_positive_volumes)
>>> print("Non positive areas:", result.has_non_positive_areas)
>>> print("Invalid shape:", result.has_invalid_shape)
>>> print("Left handed faces:", result.has_left_handed_faces)

Non positive volumes :  False
Non positive areas :  False
Invalid shape :  False
Left handed faces :  False