.. _ref_index_mesh_diagnostics: **************** Mesh diagnostics **************** =========================== Mesh statistics and quality =========================== You can use a set of quality metrics to measure the mesh quality. The :class:`SurfaceSearch ` and :class:`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 :func:`SurfaceSearch.get_surface_diagnostic_summary() ` method. The :class:`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: .. code-block:: python # 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: .. code-block:: pycon >>> 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 :class:`FaceQualityMeasure ` class offers various types of measures to verify face quality metrics. * The :attr:`SKEWNESS ` metric ranges between 0 (ideal) and 1 (worst). * The :attr:`ASPECTRATIO ` metric is greater than 1. The smaller the aspect ratio, the higher the quality of an element. * The :attr:`ELEMENTQUALITY ` metric ranges between 0 (worst) and 1 (ideal). This code gets face quality measures: .. code-block:: python 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: .. code-block:: pycon >>> 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 :class:`CellQualityMeasure ` class offers various types of measures to verify cell quality metrics. * The :attr:`SKEWNESS ` metric ranges between 0 (ideal) and 1 (worst). * The :attr:`ASPECTRATIO ` metric is greater than 1. The smaller the aspect ratio, the higher the quality of an element. * The :attr:`FLUENTASPECTRATIO ` metric is greater than 1. The smaller the Fluent aspect ratio, the higher the quality of an element. * The :attr:`ELEMENTQUALITY ` metric ranges between 0 (worst) and 1 (ideal). This code gets cell quality measures: .. code-block:: python 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: .. code-block:: pycon >>> 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 :func:`Part.get_summary() ` method provides the number of nodes, faces, or cells after meshing with the given parameters. This code gets mesh counts: .. code-block:: python part_summary_res = part.get_summary( prime.PartSummaryParams(model=model, print_id=False, print_mesh=True) ) This code prints mesh counts: .. code-block:: pycon >>> 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 :class:`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 :func:`VolumeMeshTool.improve_by_auto_node_move() ` method with given parameters. In addition, you can verify the mesh using the :func:`VolumeMeshTool.check_mesh() ` method. This code improves and checks the volume mesh: .. code-block:: python # 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: .. code-block:: pycon >>> 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