.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/gallery_examples/gallery/08_lucid_generic_f1_rear_wing.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_gallery_examples_gallery_08_lucid_generic_f1_rear_wing.py: .. _ref_generic_f1_rw: ============================================================= Mesh a generic F1 car rear wing for external aero simulation ============================================================= **Summary**: This example demonstrates how to generate a mesh for a generic F1 rear wing STL file model. Objective ~~~~~~~~~~ The example connects various parts of a rear wing from a generic F1 car and volume meshes the resulting model using a poly-hexcore mesh containing prisms. To simplify the process and enhance convenience, this example uses multiple meshing utilities provided in the ``lucid`` class. .. image:: ../../../images/generic_rear_wing.png :align: center :width: 800 :alt: Generic F1 rear wing. Procedure ~~~~~~~~~~ * Launch an Ansys Prime Server instance and instantiate the meshing utilities from the ``lucid`` class. * Import and append the STL geometry files for each part of the F1 rear wing. * Merge all imported components into a single part. * Use the connect operation to join the components together. * Define local size controls on aero surfaces. * Generate a surface mesh with curvature sizing. * Compute volume zones and define the fluid zone type. * Define the boundary layer. * Generate a volume mesh using poly-hexcore elements and apply boundary layer refinement. * Print statistics on the generated mesh. * Write a CAS file for use in the Fluent solver. * Exit the PyPrimeMesh session. .. GENERATED FROM PYTHON SOURCE LINES 64-70 Launch Ansys Prime Server ~~~~~~~~~~~~~~~~~~~~~~~~~ Import all necessary modules. Launch an instance of Ansys Prime Server. Connect the PyPrimeMesh client and get the model. Instantiate meshing utilities from the ``lucid`` class. .. GENERATED FROM PYTHON SOURCE LINES 70-81 .. code-block:: Python import os import tempfile import ansys.meshing.prime as prime from ansys.meshing.prime.graphics import Graphics prime_client = prime.launch_prime() model = prime_client.model mesh_util = prime.lucid.Mesh(model=model) .. GENERATED FROM PYTHON SOURCE LINES 82-87 Import geometry ~~~~~~~~~~~~~~~ Download the generic F1 rear wing geometries (STL files). Import each geometry and append to the model. Display the imported geometry. .. GENERATED FROM PYTHON SOURCE LINES 87-101 .. code-block:: Python f1_rw_drs = prime.examples.download_f1_rw_drs_stl() f1_rw_enclosure = prime.examples.download_f1_rw_enclosure_stl() f1_rw_end_plates = prime.examples.download_f1_rw_end_plates_stl() f1_rw_main_plane = prime.examples.download_f1_rw_main_plane_stl() for file_name in [f1_rw_drs, f1_rw_enclosure, f1_rw_end_plates, f1_rw_main_plane]: mesh_util.read(file_name, append=True) # display the rear wing geometry without the enclosure display = Graphics(model) scope = prime.ScopeDefinition(model, part_expression="* !*enclosure*") display(scope=scope) .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_08_lucid_generic_f1_rear_wing_001.png :alt: 08 lucid generic f1 rear wing :srcset: /examples/gallery_examples/gallery/images/sphx_glr_08_lucid_generic_f1_rear_wing_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 102-106 Merge parts ~~~~~~~~~~~ Establish the global size parameter to regulate mesh refinement. Merge all individual parts into a unified part named ``f1_car_rear_wing``. .. GENERATED FROM PYTHON SOURCE LINES 106-119 .. code-block:: Python # Define global sizes model.set_global_sizing_params(prime.GlobalSizingParams(model, min=4, max=32, growth_rate=1.2)) # Create label per part for part in model.parts: part.add_labels_on_zonelets([part.name.split(".")[0]], part.get_face_zonelets()) # Merge parts merge_params = prime.MergePartsParams(model, merged_part_suggested_name="f1_car_rear_wing") merge_result = model.merge_parts([part.id for part in model.parts], merge_params) part = model.get_part_by_name(merge_result.merged_part_assigned_name) .. GENERATED FROM PYTHON SOURCE LINES 120-127 Mesh connect ~~~~~~~~~~~~ To generate a volume mesh for a closed domain, it is necessary to ensure that the components of the rear wing are properly connected. To achieve this, perform a connect operation using labels to join the components of the rear wing. Afterward, inspect the mesh to detect any edges that are not connected. .. GENERATED FROM PYTHON SOURCE LINES 127-142 .. code-block:: Python # Connect faces mesh_util.connect_faces(part.name, face_labels="*", target_face_labels="*", tolerance=0.02) # Diagnostics surf_diag = prime.SurfaceSearch(model) surf_report = surf_diag.get_surface_diagnostic_summary( prime.SurfaceDiagnosticSummaryParams( model, compute_free_edges=True, compute_self_intersections=True, ) ) print(f"Total number of free edges present is {surf_report.n_free_edges}") .. rst-class:: sphx-glr-script-out .. code-block:: none Total number of free edges present is 0 .. GENERATED FROM PYTHON SOURCE LINES 143-155 Define local size control and generate size-field ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To accurately represent the physics of the DRS wing, a limitation of 8 mm is imposed on the mesh size of the wing. This is accomplished by implementing a curvature size control, which refines the mesh according to the curvature of the DRS surfaces. Additionally, to accurately capture the curved surfaces of other sections of the wing, curvature control is defined with a normal angle of 18 degrees. These controls are used during surface mesh generation. A volumetric size field is then computed based on the defined size controls. The volumetric size field plays a crucial role in controlling the growth and refinement of the volume mesh. .. GENERATED FROM PYTHON SOURCE LINES 155-188 .. code-block:: Python # Local curvature size control for DRS curv_size_control = model.control_data.create_size_control(prime.SizingType.CURVATURE) curv_size_params = prime.CurvatureSizingParams(model, normal_angle=18, max=4) curv_size_control.set_curvature_sizing_params(curv_size_params) curv_scope = prime.ScopeDefinition( model, entity_type=prime.ScopeEntity.FACEZONELETS, part_expression="f1_car_rear_wing*", label_expression="*drs*", ) curv_size_control.set_scope(curv_scope) curv_size_control.set_suggested_name("curvature_drs") # Global curvature size control on all face zones of the rear wing curv_size_control_global = model.control_data.create_size_control(prime.SizingType.CURVATURE) curv_size_params_global = prime.CurvatureSizingParams(model, normal_angle=18, min=8) curv_size_control_global.set_curvature_sizing_params(curv_size_params_global) curv_scope = prime.ScopeDefinition( model, entity_type=prime.ScopeEntity.FACEZONELETS, part_expression="f1_car_rear_wing*", ) curv_size_control_global.set_scope(curv_scope) curv_size_control_global.set_suggested_name("curvature_global") # Compute volumetric sizefield compute_size = prime.SizeField(model) vol_sf_params = prime.VolumetricSizeFieldComputeParams(model) compute_size.compute_volumetric( [curv_size_control.id, curv_size_control_global.id], volumetric_sizefield_params=vol_sf_params ) .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 189-194 Generate surface mesh ~~~~~~~~~~~~~~~~~~~~~ Create a surface mesh for the rear wing using the defined size controls. To facilitate the definition of boundary conditions on the surfaces in the solver, generate face zones by utilizing the existing labels found in the rear wing model. .. GENERATED FROM PYTHON SOURCE LINES 194-203 .. code-block:: Python mesh_util.surface_mesh_with_size_controls(size_control_names="*curvature*") scope = prime.ScopeDefinition(model, label_expression="* !*enclosure*") display(scope=scope) # Create face zones per label for label in part.get_labels(): mesh_util.create_zones_from_labels(label_expression=label) .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_08_lucid_generic_f1_rear_wing_002.png :alt: 08 lucid generic f1 rear wing :srcset: /examples/gallery_examples/gallery/images/sphx_glr_08_lucid_generic_f1_rear_wing_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 204-207 Compute volumetric regions ~~~~~~~~~~~~~~~~~~~~~~~~~~ Compute the volume zones. .. GENERATED FROM PYTHON SOURCE LINES 207-210 .. code-block:: Python mesh_util.compute_volumes(part_expression=part.name, create_zones_per_volume=True) .. GENERATED FROM PYTHON SOURCE LINES 211-220 Define volume controls ~~~~~~~~~~~~~~~~~~~~~~ To prevent the generation of a volume mesh within the solid wing, the type of a volume zone within the rear wing can be defined as "dead." To accomplish this, Volume Control is utilized to assign the type for the specific volume zone. Expressions are employed to define the volume zones that need to be filled, with ``* !f1_rw_enclosure`` indicating that it applies to all volume zones except for ``f1_rw_enclosure``. .. GENERATED FROM PYTHON SOURCE LINES 220-234 .. code-block:: Python volume_control = model.control_data.create_volume_control() volume_control.set_params( prime.VolumeControlParams( model, cell_zonelet_type=prime.CellZoneletType.DEAD, ) ) volume_control.set_scope( prime.ScopeDefinition( model, evaluation_type=prime.ScopeEvaluationType.ZONES, zone_expression="* !f1_rw_enclosure" ) ) .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 235-242 Define prism controls ~~~~~~~~~~~~~~~~~~~~~ A prism control can be used to define inflation layers on the external aero surfaces. Specify the aero surfaces using labels. Here prism scope is defined on zones associated with labels ``*drs*`` and ``*plane*``. The growth for the prism layer is controlled by defining the offset type to be ``uniform`` with a first height of 0.5mm . .. GENERATED FROM PYTHON SOURCE LINES 242-270 .. code-block:: Python prism_control = model.control_data.create_prism_control() prism_control.set_surface_scope( prime.ScopeDefinition( model, evaluation_type=prime.ScopeEvaluationType.LABELS, entity_type=prime.ScopeEntity.FACEZONELETS, label_expression="*drs*, *plane*", ) ) prism_control.set_volume_scope( prime.ScopeDefinition( model, evaluation_type=prime.ScopeEvaluationType.ZONES, entity_type=prime.ScopeEntity.VOLUME, zone_expression="*f1_rw_enclosure*", ) ) prism_control.set_growth_params( prime.PrismControlGrowthParams( model, offset_type=prime.PrismControlOffsetType.UNIFORM, n_layers=5, first_height=0.5, growth_rate=1.2, ) ) .. GENERATED FROM PYTHON SOURCE LINES 271-274 Generate volume mesh ~~~~~~~~~~~~~~~~~~~~ Volume mesh with hexcore polyhedral elements and boundary layer refinement. .. GENERATED FROM PYTHON SOURCE LINES 274-285 .. code-block:: Python volume_mesh = prime.AutoMesh(model) auto_mesh_param = prime.AutoMeshParams( model, prism_control_ids=[prism_control.id], size_field_type=prime.SizeFieldType.VOLUMETRIC, volume_fill_type=prime.VolumeFillType.HEXCOREPOLY, volume_control_ids=[volume_control.id], ) volume_mesh.mesh(part.id, auto_mesh_param) .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 286-288 Print mesh statistics ~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 288-319 .. code-block:: Python # Get meshed part part = model.get_part_by_name("f1_car_rear_wing") # Get statistics on the mesh part_summary_res = part.get_summary(prime.PartSummaryParams(model=model)) # Get element quality on all parts in the model search = prime.VolumeSearch(model=model) params = prime.VolumeQualitySummaryParams( model=model, scope=prime.ScopeDefinition(model=model, part_expression="*"), cell_quality_measures=[prime.CellQualityMeasure.INVERSEORTHOGONAL], quality_limit=[0.9], ) results = search.get_volume_quality_summary(params=params) # Print statistics on meshed part print(part_summary_res) print( "\nMaximum inverse-orthoginal quality of the volume mesh : ", results.quality_results_part[0].max_quality, ) # Mesh check result = prime.VolumeMeshTool(model).check_mesh(part.id, params=prime.CheckMeshParams(model)) print("\nMesh check", result, sep="\n") scope = prime.ScopeDefinition(model, part_expression="*", label_expression="* !*enclosure*") display(scope=scope) .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_08_lucid_generic_f1_rear_wing_003.png :alt: 08 lucid generic f1 rear wing :srcset: /examples/gallery_examples/gallery/images/sphx_glr_08_lucid_generic_f1_rear_wing_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none message : Part Name: f1_car_rear_wing Part ID: 6 0 Edge Zonelets 4 Face Zonelets 1 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 4 Face Zones Face Zone Name(s) : [f1_rw_drs.1, f1_rw_enclosure.1, f1_rw_end_plates.1, f1_rw_main_plane.1] 2 Volume Zones Volume Zone Name(s) : [f1_rw_enclosure, f1_rw_end_plates] 4 Label(s) Names: [f1_rw_drs, f1_rw_enclosure, f1_rw_end_plates, f1_rw_main_plane] Bounding box (-1500 -900 -300) (500 900 1200) Mesh Summary: 1611533 Nodes 73401 Poly Faces 0 Quad Faces 0 Tri Faces 73401 Faces 588891 Poly Cells 0 Hex Cells 0 Prism Cells 0 Pyramid Cells 0 Tet Cells 588891 Cells n_topo_edges : 0 n_topo_faces : 0 n_topo_volumes : 0 n_edge_zonelets : 0 n_face_zonelets : 4 n_cell_zonelets : 1 n_edge_zones : 0 n_face_zones : 4 n_volume_zones : 2 n_labels : 4 n_nodes : 1611533 n_faces : 73401 n_cells : 588891 n_tri_faces : 0 n_poly_faces : 73401 n_quad_faces : 0 n_tet_cells : 0 n_pyra_cells : 0 n_prism_cells : 0 n_poly_cells : 588891 n_hex_cells : 0 n_unmeshed_topo_faces : 0 Maximum inverse-orthoginal quality of the volume mesh : 0.873838 Mesh check has_non_positive_volumes : False has_non_positive_areas : False has_invalid_shape : False has_left_handed_faces : False error_code : ErrorCode.NOERROR warning_codes : [] .. GENERATED FROM PYTHON SOURCE LINES 320-323 Write mesh ~~~~~~~~~~ Export as CAS file for external aero simulations. .. GENERATED FROM PYTHON SOURCE LINES 323-332 .. code-block:: Python with tempfile.TemporaryDirectory() as temp_folder: print(temp_folder) mesh_file = os.path.join(temp_folder, "f1_rear_wing_vol_mesh.cas") mesh_util.write(mesh_file) assert os.path.exists(mesh_file) print("\nExported file:\n", mesh_file) .. rst-class:: sphx-glr-script-out .. code-block:: none /tmp/tmp_1fk8y69 Exported file: /tmp/tmp_1fk8y69/f1_rear_wing_vol_mesh.cas .. GENERATED FROM PYTHON SOURCE LINES 333-335 Exit PyPrimeMesh ~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 335-337 .. code-block:: Python prime_client.exit() .. rst-class:: sphx-glr-timing **Total running time of the script:** (1 minutes 18.026 seconds) .. _sphx_glr_download_examples_gallery_examples_gallery_08_lucid_generic_f1_rear_wing.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 08_lucid_generic_f1_rear_wing.ipynb <08_lucid_generic_f1_rear_wing.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 08_lucid_generic_f1_rear_wing.py <08_lucid_generic_f1_rear_wing.py>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_