.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/gallery_examples/gallery/10_wheel_ground_contact_patch.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_10_wheel_ground_contact_patch.py: .. _ref_contact_patch: ======================================================================== Create a contact patch for wrapping between a wheel and ground interface ======================================================================== **Summary**: This example demonstrates how to create a contact patch for use with wrapping to avoid meshing into a narrow contact region between two objects. Objective ~~~~~~~~~ This example uses a contact patch for wrapping to avoid the interface of a wheel with the ground to improve mesh quality when growing prism layers in the region of the contacting faces. .. image:: ../../../images/contact_patch.png :align: center :width: 600 The preceding image shows the following: * Top left: Wheel/ground interface * Top right: Addition of contact patch * Lower left: Grouping tolerance at 4 with multiple contact patches * Lower right: Grouping tolerance at 20 with merged single contact patch Procedure ~~~~~~~~~ #. Launch an Ansys Prime Server instance and instantiate the meshing utilities from the ``lucid`` class. #. Import the wheel ground geometry. #. Convert the topo parts to mesh parts so that the contact patch can be created. #. Create a contact patch between the wheel and the ground. #. Extract the fluid region using wrapping. #. Volume mesh with polyhedral and prism cells. #. Write a CAS file for use in the Fluent solver. #. Exit the PyPrimeMesh session. .. GENERATED FROM PYTHON SOURCE LINES 68-73 Launch Ansys Prime Server ~~~~~~~~~~~~~~~~~~~~~~~~~ Import all necessary modules and launch an instance of Ansys Prime Server. From the PyPrimeMesh client, get the model. Instantiate meshing utilities from the ``lucid`` class. .. GENERATED FROM PYTHON SOURCE LINES 73-85 .. code-block:: Python import os import tempfile import ansys.meshing.prime as prime from ansys.meshing.prime.graphics import PrimePlotter client = prime.launch_prime() model = client.model mesh_util = prime.lucid.Mesh(model) .. GENERATED FROM PYTHON SOURCE LINES 86-92 Import CAD geometry ~~~~~~~~~~~~~~~~~~~ Download the wheel ground geometry (FMD) file exported by SpaceClaim. Import the CAD geometry. The geometry consists of two topo parts: a wheel and an enclosing box. Labels are defined for the ground topo face on the enclosure and for the wheel as all the topo faces of the wheel part. .. GENERATED FROM PYTHON SOURCE LINES 92-106 .. code-block:: Python # For Windows OS users, SCDOC or DSCO is also available. For example: # wheel_ground_file = prime.examples.download_wheel_ground_scdoc() wheel_ground_file = prime.examples.download_wheel_ground_fmd() mesh_util.read(wheel_ground_file) display = PrimePlotter() display.plot(model, scope=prime.ScopeDefinition(model, label_expression="ground, wheel")) display.show() print(model) .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_001.png :alt: 10 wheel ground contact patch :srcset: /examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_001.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_001.vtksz .. rst-class:: sphx-glr-script-out .. code-block:: none Part Summary: Part Name: enclosure Part ID: 2 12 Topo Edges 6 Topo Faces 1 Topo Volumes 0 Edge Zones Edge Zone Name(s) : [] 0 Face Zones Face Zone Name(s) : [] 1 Volume Zones Volume Zone Name(s) : [enclosure] 6 Label(s) Names: [back, front, ground, side_left, side_right, top] Bounding box (0 -2.27596e-12 0) (453.2 774.6 655.059) Part Name: wheel_body Part ID: 3 1900 Topo Edges 722 Topo Faces 1 Topo Volumes 0 Edge Zones Edge Zone Name(s) : [] 0 Face Zones Face Zone Name(s) : [] 1 Volume Zones Volume Zone Name(s) : [wheel_body] 1 Label(s) Names: [wheel] Bounding box (129.1 119.571 0.0160347) (324.1 655.029 535.503) .. GENERATED FROM PYTHON SOURCE LINES 107-111 Convert topo parts to mesh parts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Convert the faceted geometry of the topology to mesh for all parts as the contact patch requires face zonelets from mesh parts as input. .. GENERATED FROM PYTHON SOURCE LINES 111-117 .. code-block:: Python wheel_part = model.get_part_by_name("wheel_body") enclosure_part = model.get_part_by_name("enclosure") [part.delete_topo_entities(prime.DeleteTopoEntitiesParams(model)) for part in model.parts] .. rst-class:: sphx-glr-script-out .. code-block:: none [, ] .. GENERATED FROM PYTHON SOURCE LINES 118-131 Create a contact patch ~~~~~~~~~~~~~~~~~~~~~~ To create a contact patch, a direction is needed to define the resulting shape of the patch. A new part is created containing the patch. A prefix can be specified for the label created for the contact patch face zonelets generated. The offset distance determines the thickness and extent of the patch. The source face zonelet is offset to intersect the planar target face and the intersection used to define the contact patch. Due to the depth of the treads on the wheel, 20.0 is used as the offset to reach the tire surface. If multiple contact regions are found, they can be merged by grouping them using the grouping tolerance distance. With a grouping tolerance of 4.0, separate contact regions are created for some of the treads of the tire, see the image at the top of the example. To merge these contact regions into a single patch, the grouping tolerance distance is increased to 20.0, avoiding small gaps between contact regions. .. GENERATED FROM PYTHON SOURCE LINES 131-158 .. code-block:: Python # The face zonelets of the wheel are defined as the source. # The planar surface must be specified as the target. # In this instance, the ground provides the planar target. source = wheel_part.get_face_zonelets() target = enclosure_part.get_face_zonelets_of_label_name_pattern( "ground", prime.NamePatternParams(model) ) params = prime.CreateContactPatchParams( model, contact_patch_axis=prime.ContactPatchAxis.Z, offset_distance=20.0, grouping_tolerance=20.0, suggested_label_prefix="patch", ) result = prime.SurfaceUtilities(model).create_contact_patch( source_zonelets=source, target_zonelets=target, params=params ) print(result.error_code) print(model) display = PrimePlotter() display.plot(model, scope=prime.ScopeDefinition(model, label_expression="ground, patch*, wheel")) display.show() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_002.png :alt: 10 wheel ground contact patch :srcset: /examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_002.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_002.vtksz .. rst-class:: sphx-glr-script-out .. code-block:: none ErrorCode.NOERROR Part Summary: Part Name: enclosure Part ID: 2 12 Edge Zonelets 6 Face Zonelets 0 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 0 Face Zones Face Zone Name(s) : [] 1 Volume Zones Volume Zone Name(s) : [enclosure] 6 Label(s) Names: [back, front, ground, side_left, side_right, top] Bounding box (0 -2.27596e-12 0) (453.2 774.6 655.059) Part Name: wheel_body Part ID: 3 1900 Edge Zonelets 722 Face Zonelets 0 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 0 Face Zones Face Zone Name(s) : [] 1 Volume Zones Volume Zone Name(s) : [wheel_body] 1 Label(s) Names: [wheel] Bounding box (129.1 119.571 0.0160347) (324.1 655.029 535.503) Part Name: __contact_patch__ Part ID: 4 2 Edge Zonelets 1 Face Zonelets 0 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 0 Face Zones Face Zone Name(s) : [] 0 Volume Zones Volume Zone Name(s) : [] 1 Label(s) Names: [patch___contact_patch__] Bounding box (131.625 284.78 -20) (321.583 488.729 60) .. GENERATED FROM PYTHON SOURCE LINES 159-164 Wrap the fluid region ~~~~~~~~~~~~~~~~~~~~~ The largest internal region in this instance is the fluid region around the wheel. Intersection loops are created to capture the features at the corners between the patch, ground, and wheel. .. GENERATED FROM PYTHON SOURCE LINES 164-186 .. code-block:: Python model.set_global_sizing_params(prime.GlobalSizingParams(model, min=4.0, max=100.0, growth_rate=1.4)) # Create a size control to limit the size of mesh on the wheel. size_control = model.control_data.create_size_control(prime.SizingType.SOFT) size_control.set_soft_sizing_params(prime.SoftSizingParams(model=model, max=8.0)) size_control.set_scope(prime.ScopeDefinition(model=model, label_expression="wheel")) wrap_part = mesh_util.wrap( min_size=4.0, max_size=100.0, region_extract=prime.WrapRegion.LARGESTINTERNAL, create_intersection_loops=True, wrap_size_controls=[size_control], ) # display = PrimePlotter() # display.plot(model, scope=prime.ScopeDefinition(model, label_expression="ground, patch*, wheel")) # display.show() print(model) .. rst-class:: sphx-glr-script-out .. code-block:: none Part Summary: Part Name: __wrap__ Part ID: 5 1 Edge Zonelets 610 Face Zonelets 0 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 0 Face Zones Face Zone Name(s) : [] 1 Volume Zones Volume Zone Name(s) : [enclosure.1] 14 Label(s) Names: [___geom_features___, __contact_patch__, __extracted__features__, __intersect_loops__, back, enclosure, front, ground, patch___contact_patch__, side_left, side_right, top, wheel, wheel_body] Bounding box (0 -2.27596e-12 -20) (453.2 774.6 655.059) .. GENERATED FROM PYTHON SOURCE LINES 187-190 Volume mesh ~~~~~~~~~~~ Apply five layers of prisms to the wheel, patch, and ground. Mesh with polyhedrals. .. GENERATED FROM PYTHON SOURCE LINES 190-213 .. code-block:: Python model.set_global_sizing_params(prime.GlobalSizingParams(model, min=4.0, max=100.0, growth_rate=1.4)) mesh_util.volume_mesh( volume_fill_type=prime.VolumeFillType.POLY, prism_layers=5.0, prism_surface_expression="wheel, patch*, ground", prism_volume_expression="*", scope=prime.lucid.VolumeScope(part_expression=wrap_part.name), ) display = PrimePlotter() display.plot( model, scope=prime.ScopeDefinition(model, label_expression="!front !side_right !top"), update=True, ) display.show() mesh_util.create_zones_from_labels() wrap_part._print_mesh = True print(wrap_part) .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_003.png :alt: 10 wheel ground contact patch :srcset: /examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_003.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_10_wheel_ground_contact_patch_003.vtksz .. rst-class:: sphx-glr-script-out .. code-block:: none Part Name: __wrap__ Part ID: 5 1 Edge Zonelets 610 Face Zonelets 1 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 8 Face Zones Face Zone Name(s) : [wheel_wheel_body, __contact_patch___patch___contact_patch__, enclosure_side_left, enclosure_side_right, enclosure_front, back_enclosure, enclosure_ground, enclosure_top] 1 Volume Zones Volume Zone Name(s) : [enclosure.1] 14 Label(s) Names: [___geom_features___, __contact_patch__, __extracted__features__, __intersect_loops__, back, enclosure, front, ground, patch___contact_patch__, side_left, side_right, top, wheel, wheel_body] Bounding box (0 -2.27596e-12 -20) (453.2 774.6 655.059) Mesh Summary: 853831 Nodes 50419 Poly Faces 0 Quad Faces 0 Tri Faces 50419 Faces 322306 Poly Cells 0 Hex Cells 0 Prism Cells 0 Pyramid Cells 0 Tet Cells 322306 Cells .. GENERATED FROM PYTHON SOURCE LINES 214-217 Write model ~~~~~~~~~~~ Write a CAS file for use in the Fluent solver. .. GENERATED FROM PYTHON SOURCE LINES 217-227 .. code-block:: Python with tempfile.TemporaryDirectory() as temp_folder: wheel_model = os.path.join(temp_folder, "wheel_ground_contact.cas.h5") prime.FileIO(model).export_fluent_case( wheel_model, export_fluent_case_params=prime.ExportFluentCaseParams(model, cff_format=True), ) assert os.path.exists(wheel_model) print(f"Fluent case exported at {wheel_model}") .. rst-class:: sphx-glr-script-out .. code-block:: none Fluent case exported at /tmp/tmp79y62ysr/wheel_ground_contact.cas.h5 .. GENERATED FROM PYTHON SOURCE LINES 228-230 Exit the PyPrimeMesh session ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 230-232 .. code-block:: Python client.exit() .. rst-class:: sphx-glr-timing **Total running time of the script:** (5 minutes 20.030 seconds) .. _sphx_glr_download_examples_gallery_examples_gallery_10_wheel_ground_contact_patch.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 10_wheel_ground_contact_patch.ipynb <10_wheel_ground_contact_patch.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 10_wheel_ground_contact_patch.py <10_wheel_ground_contact_patch.py>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_